/**
   @file sys_usw_scl.c


   @date 2017-01-24

   @version v5.0

   The file contains all scl APIs of sys layer

 */
/****************************************************************************
*
* Header Files
*
****************************************************************************/
#include "sal.h"

#include "ctc_error.h"
#include "ctc_hash.h"
#include "ctc_spool.h"
#include "ctc_const.h"
#include "ctc_vlan.h"
#include "ctc_qos.h"
#include "ctc_linklist.h"
#include "ctc_debug.h"
#include "ctc_vector.h"


#include "sys_usw_fpa.h"
#include "sys_usw_ftm.h"
#include "sys_usw_common.h"
#include "sys_usw_chip.h"
#include "sys_usw_opf.h"
#include "sys_usw_scl.h"
#include "sys_usw_wb_common.h"
#include "sys_usw_register.h"

#include "drv_api.h"
#include "usw/include/drv_common.h"
/****************************************************************************
 *
 * Defines and Macros
 *
 *****************************************************************************/


/****************************************************************
*
* Global and Declaration
*
****************************************************************/


/*software hash size, determined by scl owner.*/
#define SYS_SCL_FLEX_KEY_VEC_SIZE               256
#define SYS_SCL_FLEX_KEY_VEC_BLOCK_SIZE         16
#define SYS_SCL_DEF_ENTRY_VEC_SIZE              (SCL_HASH_NUM * SYS_USW_MAX_PORT_NUM_PER_CHIP * (SYS_SCL_ACTION_TUNNEL+1))
#define SYS_SCL_DEF_ENTRY_VEC_BLOCK_SIZE        32
#define SYS_SCL_GROUP_HASH_SIZE                 1024
#define SYS_SCL_ENTRY_HASH_SIZE                 ((SYS_FTM_SPEC(lchip, CTC_FTM_SPEC_SCL_FLOW)+SYS_FTM_SPEC(lchip, CTC_FTM_SPEC_SCL)+SYS_FTM_SPEC(lchip, CTC_FTM_SPEC_TUNNEL))/SYS_HASH_SIZE_COMPRESS_RATE_4)
#define SYS_SCL_ENTRY_BY_KEY_HASH_SIZE          32768
#define SYS_SCL_TCAM_ENTRY_BY_KEY_HASH_SIZE     1024
#define SYS_SCL_XKEY_TYPE_HASH_SIZE             256
#define SYS_SCL_VLAN_EDIT_SPOOL_BLOCK_SIZE      64
#define SYS_SCL_AD_SPOOL_BLOCK_SIZE             1024
#define SYS_SCL_WB_DATA(wb_data)      (wb_data)
#define SYS_SCL_COPY_DB_TO_WB(wb_data, sw_data)     \
    do {\
            wb_data = sw_data;\
    }while(0)
#define SYS_SCL_DEF_K(DIR, TYPE) \
            p_kset = p_usw_scl_master[lchip]->kset_db[DIR][TYPE];\
            CTC_BMP_SET(key_type_bmp[DIR], (TYPE));
#define SYS_SCL_DEF_F(FIELD)            CTC_BMP_SET(((p_kset)->w), (FIELD));

#define SYS_SCL_IS_ENTRY_HASH_BITMAP(entry_id,group_id)\
        ((SCL_INNER_ENTRY_ID(entry_id))                             \
                &&(((((group_id)>>20) & 0xFF) == CTC_FEATURE_SRV6)  \
                ||((((group_id)>>20) & 0xFF) == CTC_FEATURE_IP_TUNNEL)   \
                ||((((group_id)>>20) & 0xFF) == CTC_FEATURE_OVERLAY)\
                ||((((group_id)>>20) & 0xFF) == CTC_FEATURE_VLAN_MAPPING)))?TRUE:FALSE \

typedef struct sys_scl_traverse_data_s
{
    void* data0;
    void* data1;
    int32 value0;
    uint32 value1;
}sys_scl_traverse_data_t;

/****************************************************************
*
* Functions
*
****************************************************************/
extern int32 _sys_usw_scl_bind_nexthop(uint8 lchip, sys_scl_sw_entry_t* pe,uint32 nh_id);
extern int32
_sys_usw_scl_map_drv_tunnel_type(uint8 lchip, uint8 key_type, uint8* p_drv_key_type);

sys_scl_master_t* p_usw_scl_master[CTC_MAX_LOCAL_CHIP_NUM_PP] = {NULL};

#define __hash_and_spool_register_function__
STATIC uint32
_sys_usw_scl_group_hash_make(sys_scl_sw_group_t* pg)
{
    return pg->group_id;
}

STATIC bool
_sys_usw_scl_group_hash_compare(sys_scl_sw_group_t* pg0, sys_scl_sw_group_t* pg1)
{
    return(pg0->group_id == pg1->group_id);
}

STATIC uint32
_sys_usw_scl_entry_hash_make(sys_scl_sw_entry_t* pe)
{
    return pe->entry_id;
}

STATIC bool
_sys_usw_scl_entry_hash_compare(sys_scl_sw_entry_t* pe0, sys_scl_sw_entry_t* pe1)
{
    return(pe0->entry_id == pe1->entry_id);
}

STATIC uint32
_sys_usw_scl_tcam_entry_by_key_hash_make(sys_scl_tcam_entry_key_t* p_tcam_entry)
{
    uint32 size = 0;
    uint8  * k = NULL;

    CTC_PTR_VALID_CHECK(p_tcam_entry);

    size = sizeof(sys_scl_tcam_entry_key_t) - sizeof(sys_scl_sw_entry_t*);
    k    = (uint8 *) p_tcam_entry;

    return ctc_hash_caculate(size, k);
}

STATIC bool
_sys_usw_scl_tcam_entry_by_key_hash_compare(sys_scl_tcam_entry_key_t* p_tcam_entry0, sys_scl_tcam_entry_key_t* p_tcam_entry1)
{
    if (!p_tcam_entry0 || !p_tcam_entry1)
    {
        return FALSE;
    }

    if (sal_memcmp(p_tcam_entry0->key, p_tcam_entry1->key, SYS_SCL_MAX_KEY_SIZE_IN_WORD * 4)\
        || sal_memcmp(p_tcam_entry0->mask, p_tcam_entry1->mask, SYS_SCL_MAX_KEY_SIZE_IN_WORD * 4) || p_tcam_entry0->scl_id != p_tcam_entry1->scl_id)
    {
        return FALSE;
    }

    return TRUE;
}

STATIC uint32
_sys_usw_scl_hash_key_entry_make(sys_scl_hash_key_entry_t* pe)
{
    uint8  hash_seeds[20] = {0};
    uint8  hash_seeds_size = 0 ;
    uint32 value = 0;
    sal_memcpy((uint8*)&hash_seeds[0],(uint8*)&pe->key_index,sizeof(uint32));
    hash_seeds[4] = pe->action_type;
    hash_seeds_size = 5;
    value = ctc_hash_caculate(hash_seeds_size, hash_seeds);
    return value;
}

STATIC bool
_sys_usw_scl_hash_key_entry_compare(sys_scl_hash_key_entry_t* pe0, sys_scl_hash_key_entry_t* pe1)
{
    if (!pe0 || !pe1)
    {
        return FALSE;
    }

    if ((pe0->action_type!= pe1->action_type)  || (pe0->key_index != pe1->key_index) || (pe0->scl_id != pe1->scl_id))
    {
        return FALSE;
    }

    return TRUE;
}

STATIC uint32
_sys_usw_scl_vlan_edit_spool_make(sys_scl_sp_vlan_edit_t* pv)
{
    uint32 size = 0;
    uint8* k = NULL;

    CTC_PTR_VALID_CHECK(pv);
    size = CTC_OFFSET_OF(sys_scl_sp_vlan_edit_t, calc_key_len);
    k = (uint8*) pv;
    return ctc_hash_caculate(size, k);
}

/* if vlan edit in bucket equals */
STATIC bool
_sys_usw_scl_vlan_edit_spool_compare(sys_scl_sp_vlan_edit_t* pv0,
                                           sys_scl_sp_vlan_edit_t* pv1)
{
    uint32 size = 0;
    if (!pv0 || !pv1)
    {
        return FALSE;
    }
    size = CTC_OFFSET_OF(sys_scl_sp_vlan_edit_t, calc_key_len);
    if (!sal_memcmp(pv0, pv1, size))
    {
        return TRUE;
    }

    return FALSE;
}

STATIC int32
_sys_usw_scl_vlan_edit_spool_alloc_index(sys_scl_sp_vlan_edit_t* pv, uint8* lchip)
{
    sys_usw_opf_t opf;
    uint32 value_32 = 0;

    sal_memset(&opf, 0, sizeof(sys_usw_opf_t));
    opf.pool_type  = p_usw_scl_master[*lchip]->opf_type_vlan_edit;

    if( CTC_WB_STATUS(*lchip) == CTC_WB_STATUS_RELOADING)
    {
        CTC_ERROR_RETURN(sys_usw_opf_alloc_offset_from_position(*lchip, &opf, 1, pv->profile_id));
    }
    else
    {
        CTC_ERROR_RETURN(sys_usw_opf_alloc_offset(*lchip, &opf, 1, &value_32));
        pv->profile_id = value_32 & 0xFFFF;
    }

    return CTC_E_NONE;
}

STATIC int32
_sys_usw_scl_vlan_edit_spool_free_index(sys_scl_sp_vlan_edit_t* pv, uint8* lchip)
{
    sys_usw_opf_t opf;
    uint32 index = pv->profile_id;

    sal_memset(&opf, 0, sizeof(sys_usw_opf_t));
    opf.pool_type  = p_usw_scl_master[*lchip]->opf_type_vlan_edit;

    CTC_ERROR_RETURN(sys_usw_opf_free_offset(*lchip, &opf, 1, index));

    return CTC_E_NONE;
}

STATIC uint32
_sys_usw_scl_get_asic_table(uint8 lchip, sys_scl_sw_igs_ad_t* ad, void* value)
{
    uint8 is_half = ad->com.is_half;
    uint8 block_id = ad->com.priority;
    uint32 act_id = 0;
    uint32 offset = ad->com.ad_index;
    uint32 cmd;

    switch (ad->com.action_type)
    {
        case SYS_SCL_ACTION_INGRESS:
            switch (block_id)
            {
                case 0:
                    act_id = is_half? DsUserIdHalf_t : DsUserId_t;
                    break;
                case 1:
                    act_id = is_half? DsUserIdHalf1_t : DsUserId1_t;
                    if (1 == MCHIP_CAP(SYS_CAP_SCL_HASH_NUM))
                    {
                        act_id = is_half? DsUserIdHalf_t : DsUserId_t;
                    }
                    break;
                case 2:
                    act_id = DsUserId2_t;
                    break;
                case 3:
                    act_id = DsUserId3_t;
                    break;
                default :
                    break;
            }
            break;
        case SYS_SCL_ACTION_TUNNEL:
            if (0 == block_id)
            {
                act_id = is_half? DsTunnelIdHalf_t : DsTunnelId_t;
            }
            else if (1 == block_id)
            {
                if (1 == MCHIP_CAP(SYS_CAP_SCL_HASH_NUM))
                {
                    act_id = is_half? DsTunnelIdHalf_t : DsTunnelId_t;
                }
                else
                {
                    act_id = is_half? DsTunnelIdHalf1_t : DsTunnelId1_t;
                }
            }
            break;
        case SYS_SCL_ACTION_FLOW:
            if (0 == block_id)
            {
                act_id = DRV_FROM_TMM(lchip)? (is_half? DsUserIdHalf_t : DsUserId_t) : DsSclFlow_t;
            }
            else if (1 == block_id)
            {
                if (1 == MCHIP_CAP(SYS_CAP_SCL_HASH_NUM))
                {
                    act_id = DRV_FROM_TMM(lchip)? (is_half? DsUserIdHalf_t : DsUserId_t) : DsSclFlow_t;
                }
                else
                {
                    act_id = DRV_FROM_TMM(lchip)? (is_half? DsUserIdHalf1_t : DsUserId1_t) : DsSclFlow1_t;
                }
            }
            else if (2 == block_id)
            {
                act_id = DRV_FROM_TMM(lchip)? DsUserId2_t : DsSclFlow2Tcam_t;
            }
            else if (3 == block_id)
            {
                act_id = DRV_FROM_TMM(lchip)? DsUserId3_t : DsSclFlow3Tcam_t;
            }
            break;

        case SYS_SCL_ACTION_MPLS:
        case SYS_SCL_ACTION_EGRESS:
        default:
            return CTC_E_INVALID_PARAM;
    }
    cmd = DRV_IOR(act_id, DRV_ENTRY_FLAG);
    if (DRV_E_NONE != DRV_IOCTL(lchip, offset, DRV_CMD_BMP_EN(cmd, MCHIP_FEATURE_PP_EN(lchip,CTC_FEATURE_SCL)), value))
    {
        SYS_SCL_DBG_OUT(CTC_DEBUG_LEVEL_ERROR, " [ASIC] Hardware operation failed \n");
        return CTC_E_HW_FAIL;
    }

    return CTC_E_NONE;
}

STATIC uint32
_sys_usw_scl_ad_spool_make(sys_scl_sw_igs_ad_t* pa)
{
    uint32 size = 0;
    DsUserId_m  action;
    void* k = NULL;

    CTC_PTR_VALID_CHECK(pa);
    size = (DRV_TABLE_ENTRY_SIZE(pa->com.lchip, DsUserId_t) >> (pa->com.is_half));
    if (SYS_SCL_INVALID_AD_INDEX != pa->com.ad_index)
    {
        _sys_usw_scl_get_asic_table(pa->com.lchip, pa, &action);
        return ctc_hash_caculate(size, &action);
    }
    switch (pa->com.ad_type)
    {
        case SYS_SCL_SW_AD_TYPE_IGS_0:
            k = (((sys_scl_sw_igs_ad0_t*)pa)->action);
            break;
        case SYS_SCL_SW_AD_TYPE_IGS_1:
            k = (((sys_scl_sw_igs_ad1_t*)pa)->action);
            break;
        case SYS_SCL_SW_AD_TYPE_IGS_2:
            k = (((sys_scl_sw_igs_ad2_t*)pa)->action);
            break;
        case SYS_SCL_SW_AD_TYPE_IGS_3:
            k = (((sys_scl_sw_igs_ad3_t*)pa)->action);
            break;
        default:
            k = (pa->action);
            break;
    }
    return ctc_hash_caculate(size, k);
}

STATIC bool
_sys_usw_scl_ad_spool_compare(sys_scl_sw_igs_ad_t* pAction0, sys_scl_sw_igs_ad_t* pAction1)
{
    uint32 size = 0;
    DsUserId_m  action0;
    DsUserId_m  action1;
    void* k = NULL;
    uint8* is_exist = NULL;

    if (!pAction0 || !pAction1)
    {
        return FALSE;
    }

    /*for spool add error rollback, SYS_SCL_INVALID_VLAN_EDIT_PROFILE_ID is return from opf*/
    if (SYS_SCL_INVALID_AD_INDEX == pAction0->com.ad_index)
    {
        return TRUE;
    }

    size = DRV_TABLE_ENTRY_SIZE(pAction0->com.lchip, DsUserId_t) >> pAction1->com.is_half;
    _sys_usw_scl_get_asic_table(pAction0->com.lchip, pAction0, &action0);

    /* for old or remove spool, input is spool node, need get ds by index*/
    if (SYS_SCL_INVALID_AD_INDEX != pAction1->com.ad_index)
    {
        _sys_usw_scl_get_asic_table(pAction1->com.lchip, pAction1, &action1);
        if (!sal_memcmp(&action1, &action0, size))
        {
            return TRUE;
        }
    }
    else
    {
        switch (pAction1->com.ad_type)
        {
            case SYS_SCL_SW_AD_TYPE_IGS_0:
                k = (((sys_scl_sw_igs_ad0_t*)pAction1)->action);
                is_exist = &(((sys_scl_sw_igs_ad0_t*)pAction1)->is_exist);
                break;
            case SYS_SCL_SW_AD_TYPE_IGS_1:
                k = (((sys_scl_sw_igs_ad1_t*)pAction1)->action);
                is_exist = &(((sys_scl_sw_igs_ad1_t*)pAction1)->is_exist);
                break;
            case SYS_SCL_SW_AD_TYPE_IGS_2:
                k = (((sys_scl_sw_igs_ad2_t*)pAction1)->action);
                is_exist = &(((sys_scl_sw_igs_ad2_t*)pAction1)->is_exist);
                break;
            case SYS_SCL_SW_AD_TYPE_IGS_3:
                k = (((sys_scl_sw_igs_ad3_t*)pAction1)->action);
                is_exist = &(((sys_scl_sw_igs_ad3_t*)pAction1)->is_exist);
                break;
            default:
                k = (pAction1->action);
                is_exist = &(pAction1->is_exist);
                break;
        }

        if (!sal_memcmp(k, &action0, size))
        {
            *is_exist = 1;
            return TRUE;
        }
    }


    return FALSE;
}

/* build index of HASH ad */
STATIC int32
_sys_usw_scl_ad_spool_alloc_index(sys_scl_sw_igs_ad_t* pAction, uint8* p_lchip)
{
    uint32  value_32 = 0;
    uint32  block_size = 0;
    uint8   multi = 0;
    uint32 tbl_id = 0;

    block_size = pAction->com.is_half ? 1 : 2;            /* warmboot will not affect this value, because it only decide distribute from which position */
    multi = pAction->com.is_half ? 1 : 2;
    tbl_id = pAction->com.priority == 1? DsUserId1_t:DsUserId_t;

    if( CTC_WB_STATUS(*p_lchip) != CTC_WB_STATUS_RELOADING)
    {
        CTC_ERROR_RETURN(sys_usw_ftm_alloc_table_offset(*p_lchip, tbl_id, 0, block_size, multi, &value_32));
        pAction->com.ad_index = value_32 & 0xFFFFF;
    }
    else
    {
        CTC_ERROR_RETURN(sys_usw_ftm_alloc_table_offset_from_position(*p_lchip, tbl_id, 0, block_size, pAction->com.ad_index));
    }

    return CTC_E_NONE;
}


/* free index of HASH ad */
STATIC int32
_sys_usw_scl_ad_spool_free_index(sys_scl_sw_igs_ad_t* pAction, uint8* lchip)
{
    uint32  block_size = 0;
    uint8   dir = 0;
    uint32  index = pAction->com.ad_index;
    uint32 tbl_id = 0;

    block_size = pAction->com.is_half ? 1 : 2;
    tbl_id = pAction->com.priority== 1? DsUserId1_t:DsUserId_t;

    CTC_ERROR_RETURN(sys_usw_ftm_free_table_offset(*lchip, tbl_id, dir, block_size, index));
    return CTC_E_NONE;
}

STATIC uint32
_sys_usw_scl_acl_profile_spool_make(sys_scl_action_acl_t* pv)
{
    uint32 size  = 0;
    uint8* k = NULL;

    CTC_PTR_VALID_CHECK(pv);
    size = CTC_OFFSET_OF(sys_scl_action_acl_t, calc_key_len);
    k = (uint8*) pv;

    return ctc_hash_caculate(size, k);
}

STATIC bool
_sys_usw_scl_acl_profile_spool_compare(sys_scl_action_acl_t* pv0,
                                           sys_scl_action_acl_t* pv1)
{
    uint32 size = 0;

    if (!pv0 || !pv1)
    {
        return FALSE;
    }

    size = CTC_OFFSET_OF(sys_scl_action_acl_t, calc_key_len);

    if (!sal_memcmp(pv0, pv1, size))
    {
        return TRUE;
    }

    return FALSE;
}

STATIC int32
_sys_usw_scl_acl_profile_spool_alloc_index(sys_scl_action_acl_t* pv, uint8* lchip)
{
    sys_usw_opf_t opf;
    uint32 value_32 = 0;

    sal_memset(&opf, 0, sizeof(sys_usw_opf_t));
    opf.pool_index = 0;
    if (pv->is_scl)
    {
        opf.pool_type  = p_usw_scl_master[*lchip]->opf_type_flow_acl_profile;
    }
    else
    {
        opf.pool_type  = p_usw_scl_master[*lchip]->opf_type_tunnel_acl_profile;
    }

    if( CTC_WB_STATUS(*lchip) == CTC_WB_STATUS_RELOADING)
    {
        CTC_ERROR_RETURN(sys_usw_opf_alloc_offset_from_position(*lchip, &opf, 1, pv->profile_id));
    }
    else
    {
        CTC_ERROR_RETURN(sys_usw_opf_alloc_offset(*lchip, &opf, 1, &value_32));
        pv->profile_id = value_32 & 0xFF;
    }

    return CTC_E_NONE;
}

STATIC int32
_sys_usw_scl_acl_profile_spool_free_index(sys_scl_action_acl_t* pv, uint8* lchip)
{
    sys_usw_opf_t opf;
    uint32 index = pv->profile_id;

    sal_memset(&opf, 0, sizeof(sys_usw_opf_t));
    opf.pool_index = 0;
    if (pv->is_scl)
    {
        opf.pool_type  = p_usw_scl_master[*lchip]->opf_type_flow_acl_profile;
    }
    else
    {
        opf.pool_type  = p_usw_scl_master[*lchip]->opf_type_tunnel_acl_profile;
    }

    CTC_ERROR_RETURN(sys_usw_opf_free_offset(*lchip, &opf, 1, index));

    return CTC_E_NONE;
}

int32
_sys_usw_scl_free_entry_node_data(void* node_data, void* user_data)
{
    uint8 lchip = 0;
    sys_scl_sw_entry_t* pe = NULL;
    sys_scl_sw_block_t* pb = NULL;
    sys_scl_sw_tcam_entry_t* pe_tcam = NULL;
    void* p_ad = NULL;

    if (user_data)
    {
        lchip= *(uint8*)user_data;
        pe = (sys_scl_sw_entry_t*)node_data;

        if (!pe->is_default && (SCL_ENTRY_IS_TCAM(pe->key_type) || pe->resolve_conflict))
        {
            pb = &p_usw_scl_master[lchip]->fpa_block[SCL_ENCODE_BLOCK_ID(pe->direction, pe->group_priority)];
            pe_tcam = (sys_scl_sw_tcam_entry_t*) pb->fpab.entries[pe->key_index];
            mem_free(pe_tcam);
        }
        if(pe->is_default || CTC_EGRESS == pe->direction || SCL_ENTRY_IS_TCAM(pe->key_type) || pe->resolve_conflict)
        {
            p_ad = (pe->is_buffer? pe->u.temp_entry->p_ad: pe->u.ad);
            mem_free(p_ad);
        }
        if (pe->is_buffer)
        {
            mem_free(pe->u.temp_entry);
        }
    }

    mem_free(node_data);

    return CTC_E_NONE;
}

int32
_sys_usw_scl_free_hash_key_node_data(void* node_data, void* user_data)
{
    mem_free(node_data);

    return CTC_E_NONE;
}

int32
_sys_usw_scl_free_vec_node_data(void* node_data, void* user_data)
{
    mem_free(node_data);

    return CTC_E_NONE;
}

int32
_sys_usw_scl_get_fk_vec_node_data(void* node_data, void* user_data)
{
    sys_scl_flexed_key_t* p_node_data = (sys_scl_flexed_key_t*)node_data;
    sys_scl_flexed_key_t* p_user_data = (sys_scl_flexed_key_t*)(((ctc_field_key_t*)user_data)->ext_data);

    if(p_node_data->origin_key_type == p_user_data->origin_key_type &&
        p_node_data->dir == p_user_data->dir)
    {
         ((ctc_field_key_t*)user_data)->ext_data = node_data;
         return -1;
    }
    return 0;
}

int32
_sys_usw_scl_free_group_node_data(void* node_data, void* user_data)
{
    mem_free(node_data);

    return CTC_E_NONE;
}

int32
_sys_usw_scl_get_compress_ipv6_addr(uint8 lchip, uint8 compress_mode, ipv6_addr_t ipv6, ipv6_addr_t ipv6_64)
{
    uint8 index = 0;
    sal_memset(ipv6_64, 0, sizeof(ipv6_addr_t));
    index = compress_mode;
    compress_mode = compress_mode > 8 ? (compress_mode - 8) : compress_mode;
    ipv6_64[0] = (((uint64)ipv6[index/9]<< (compress_mode*4))& (~((1LLU<<(compress_mode*4))-1))) | (((uint64)ipv6[(index/9)+1] >> (32-(compress_mode*4))) & ((1LLU<<(compress_mode*4))-1)) ;
    ipv6_64[1] = (((uint64)ipv6[(index/9)+1]<< (compress_mode*4))& (~((1LLU<<(compress_mode*4))-1))) | (((uint64)ipv6[(index/9)+2] >> (32-(compress_mode*4))) & ((1LLU<<(compress_mode*4))-1)) ;
    return CTC_E_NONE;
}

int32
_sys_usw_scl_free_tcam_node_data(void* node_data, void* user_data)
{
    mem_free(node_data);

    return CTC_E_NONE;
}

int32
_sys_usw_scl_get_flex_key_node(uint8 lchip, sys_scl_sw_entry_t* pe, sys_scl_flexed_key_t** p_flexed_key)
{
    sys_scl_flexed_key_t flexed_key;
    ctc_field_key_t user_data;

    if (pe->is_xkey)
    {
        if (pe->is_buffer && pe->u.temp_entry->fk)
        {
            *p_flexed_key = pe->u.temp_entry->fk;
        }
        else
        {
            sal_memset(&flexed_key, 0, sizeof(sys_scl_flexed_key_t));

            flexed_key.dir = pe->direction;
            flexed_key.origin_key_type = pe->key_type;
            user_data.ext_data = (void*)&flexed_key;
            if (FALSE == ctc_vector_traverse(p_usw_scl_master[lchip]->flex_key_vec, _sys_usw_scl_get_fk_vec_node_data, (void*)&user_data))
            {
                CTC_ERROR_RETURN(CTC_E_ENTRY_NOT_EXIST);
            }
            *p_flexed_key = (sys_scl_flexed_key_t*)user_data.ext_data;
        }
    }

    return CTC_E_NONE;
}

#define __scl_fpa_init_function__

int32
_sys_usw_scl_init_fpa(uint8 lchip)
{
    uint8 loop = 0;
    uint32 offset = 0;
    uint32 entry_size = 0;
    uint32 scl_tcam[SCL_TCAM_NUM] = {0};
    uint8  fpa_size_80 = 0;
    uint16 entry_cnt[CTC_FPA_KEY_SIZE_NUM] = {0};
#ifdef EMULATION_ENV
    scl_tcam[0] = 64;
    scl_tcam[1] = 64;
    scl_tcam[2] = 64;
    scl_tcam[3] = 64;
    scl_tcam[4] = 64;
    scl_tcam[5] = 64;
#else
    CTC_ERROR_RETURN(sys_usw_ftm_query_table_entry_num(lchip, DRV_FROM_TMM(lchip)?DsSclHash0ConflictTcamSize0_t:DsUserId0TcamKey80_t, &scl_tcam[0]));
    CTC_ERROR_RETURN(sys_usw_ftm_query_table_entry_num(lchip, DRV_FROM_TMM(lchip)?DsSclHash1ConflictTcamSize0_t:DsUserId1TcamKey80_t, &scl_tcam[1]));

    if (DRV_FROM_TM(lchip))
    {
        CTC_ERROR_RETURN(sys_usw_ftm_query_table_entry_num(lchip, DsScl2MacKey160_t, &scl_tcam[2]));
        CTC_ERROR_RETURN(sys_usw_ftm_query_table_entry_num(lchip, DsScl3MacKey160_t, &scl_tcam[3]));
        scl_tcam[2] = scl_tcam[2] * 2;
        scl_tcam[3] = scl_tcam[3] * 2;
    }

    if (DRV_FROM_TMM(lchip))
    {
        CTC_ERROR_RETURN(sys_usw_ftm_query_table_entry_num(lchip, DsEgressScl0TcamKey_t, &scl_tcam[4]));
        CTC_ERROR_RETURN(sys_usw_ftm_query_table_entry_num(lchip, DsEgressScl1TcamKey_t, &scl_tcam[5]));
    }
#endif
    fpa_size_80 = DRV_FROM_TMM(lchip)? CTC_FPA_KEY_SIZE_80 : CTC_FPA_KEY_SIZE_160;
    p_usw_scl_master[lchip]->fpa_size[SYS_SCL_KEY_TCAM_VLAN]        = CTC_FPA_KEY_SIZE_320;

    /* default mac tcam key use 160 bit  */

    p_usw_scl_master[lchip]->fpa_size[SYS_SCL_KEY_TCAM_MAC]                     = CTC_FPA_KEY_SIZE_160;

    p_usw_scl_master[lchip]->fpa_size[SYS_SCL_KEY_TCAM_IPV4_SINGLE]             = CTC_FPA_KEY_SIZE_160;
    p_usw_scl_master[lchip]->fpa_size[SYS_SCL_KEY_TCAM_IPV4]                    = CTC_FPA_KEY_SIZE_320;
    p_usw_scl_master[lchip]->fpa_size[SYS_SCL_KEY_TCAM_IPV6_SINGLE]             = CTC_FPA_KEY_SIZE_320;
    p_usw_scl_master[lchip]->fpa_size[SYS_SCL_KEY_TCAM_IPV6]                    = CTC_FPA_KEY_SIZE_640;
    p_usw_scl_master[lchip]->fpa_size[SYS_SCL_KEY_HASH_PORT]                    = fpa_size_80;
    p_usw_scl_master[lchip]->fpa_size[SYS_SCL_KEY_HASH_PORT_CVLAN]              = fpa_size_80;
    p_usw_scl_master[lchip]->fpa_size[SYS_SCL_KEY_HASH_PORT_SVLAN]              = fpa_size_80;
    p_usw_scl_master[lchip]->fpa_size[SYS_SCL_KEY_HASH_PORT_2VLAN]              = fpa_size_80;
    p_usw_scl_master[lchip]->fpa_size[SYS_SCL_KEY_HASH_PORT_SVLAN_DSCP]         = fpa_size_80;
    p_usw_scl_master[lchip]->fpa_size[SYS_SCL_KEY_HASH_PORT_CVLAN_COS]          = fpa_size_80;
    p_usw_scl_master[lchip]->fpa_size[SYS_SCL_KEY_HASH_PORT_SVLAN_COS]          = fpa_size_80;
    p_usw_scl_master[lchip]->fpa_size[SYS_SCL_KEY_HASH_MAC]                     = fpa_size_80;
    p_usw_scl_master[lchip]->fpa_size[SYS_SCL_KEY_HASH_PORT_MAC]                = CTC_FPA_KEY_SIZE_160;
    p_usw_scl_master[lchip]->fpa_size[SYS_SCL_KEY_HASH_IPV4]                    = fpa_size_80;
    p_usw_scl_master[lchip]->fpa_size[SYS_SCL_KEY_HASH_SVLAN_MAC]               = fpa_size_80;
    p_usw_scl_master[lchip]->fpa_size[SYS_SCL_KEY_HASH_SVLAN]                   = fpa_size_80;
    p_usw_scl_master[lchip]->fpa_size[SYS_SCL_KEY_HASH_PORT_IPV4]               = fpa_size_80;
    p_usw_scl_master[lchip]->fpa_size[SYS_SCL_KEY_HASH_IPV6]                    = CTC_FPA_KEY_SIZE_160;
    p_usw_scl_master[lchip]->fpa_size[SYS_SCL_KEY_HASH_IPV6_DA]                 = CTC_FPA_KEY_SIZE_160;
    p_usw_scl_master[lchip]->fpa_size[SYS_SCL_KEY_HASH_PORT_IPV6]               = CTC_FPA_KEY_SIZE_320;
    p_usw_scl_master[lchip]->fpa_size[SYS_SCL_KEY_HASH_L2]                      = CTC_FPA_KEY_SIZE_160;
    p_usw_scl_master[lchip]->fpa_size[SYS_SCL_KEY_HASH_L2_UDF]                  = CTC_FPA_KEY_SIZE_320;
    p_usw_scl_master[lchip]->fpa_size[SYS_SCL_KEY_HASH_L3_UDF]                  = CTC_FPA_KEY_SIZE_320;
    p_usw_scl_master[lchip]->fpa_size[SYS_SCL_KEY_HASH_TUNNEL_IPV4]             = CTC_FPA_KEY_SIZE_160;
    p_usw_scl_master[lchip]->fpa_size[SYS_SCL_KEY_HASH_TUNNEL_IPV4_GRE]         = CTC_FPA_KEY_SIZE_160;
    p_usw_scl_master[lchip]->fpa_size[SYS_SCL_KEY_HASH_TUNNEL_IPV4_RPF]         = fpa_size_80;
    p_usw_scl_master[lchip]->fpa_size[SYS_SCL_KEY_HASH_TUNNEL_IPV4_DA]          = fpa_size_80;
    p_usw_scl_master[lchip]->fpa_size[SYS_SCL_KEY_HASH_TUNNEL_IPV4_CLOUD_SEC]   = CTC_FPA_KEY_SIZE_160;
    p_usw_scl_master[lchip]->fpa_size[SYS_SCL_KEY_HASH_TUNNEL_IPV6]             = DRV_FROM_TMM(lchip)? CTC_FPA_KEY_SIZE_320: CTC_FPA_KEY_SIZE_640;
    p_usw_scl_master[lchip]->fpa_size[SYS_SCL_KEY_HASH_TUNNEL_IPV6_GREKEY]      = DRV_FROM_TMM(lchip)? CTC_FPA_KEY_SIZE_320: CTC_FPA_KEY_SIZE_640;
    p_usw_scl_master[lchip]->fpa_size[SYS_SCL_KEY_HASH_TUNNEL_IPV6_UDP]         = CTC_FPA_KEY_SIZE_320;
    p_usw_scl_master[lchip]->fpa_size[SYS_SCL_KEY_HASH_TUNNEL_IPV6_DA]          = DRV_FROM_TMM(lchip)? CTC_FPA_KEY_SIZE_160: CTC_FPA_KEY_SIZE_320;
    p_usw_scl_master[lchip]->fpa_size[SYS_SCL_KEY_HASH_TUNNEL_IPV6_CLOUD_SEC]   = CTC_FPA_KEY_SIZE_320;
    p_usw_scl_master[lchip]->fpa_size[SYS_SCL_KEY_HASH_NVGRE_UC_V4_MODE0]       = fpa_size_80;
    p_usw_scl_master[lchip]->fpa_size[SYS_SCL_KEY_HASH_NVGRE_UC_V4_MODE1]       = fpa_size_80;
    p_usw_scl_master[lchip]->fpa_size[SYS_SCL_KEY_HASH_NVGRE_MC_V4_MODE0]       = fpa_size_80;
    p_usw_scl_master[lchip]->fpa_size[SYS_SCL_KEY_HASH_NVGRE_V4_MODE1]          = CTC_FPA_KEY_SIZE_160;
    p_usw_scl_master[lchip]->fpa_size[SYS_SCL_KEY_HASH_NVGRE_UC_V6_MODE0]       = CTC_FPA_KEY_SIZE_320;
    p_usw_scl_master[lchip]->fpa_size[SYS_SCL_KEY_HASH_NVGRE_UC_V6_MODE1]       = CTC_FPA_KEY_SIZE_320;
    p_usw_scl_master[lchip]->fpa_size[SYS_SCL_KEY_HASH_NVGRE_MC_V6_MODE0]       = CTC_FPA_KEY_SIZE_320;
    p_usw_scl_master[lchip]->fpa_size[SYS_SCL_KEY_HASH_NVGRE_MC_V6_MODE1]       = CTC_FPA_KEY_SIZE_320;
    p_usw_scl_master[lchip]->fpa_size[SYS_SCL_KEY_HASH_VXLAN_UC_V4_MODE0]       = fpa_size_80;
    p_usw_scl_master[lchip]->fpa_size[SYS_SCL_KEY_HASH_VXLAN_UC_V4_MODE1]       = fpa_size_80;
    p_usw_scl_master[lchip]->fpa_size[SYS_SCL_KEY_HASH_VXLAN_MC_V4_MODE0]       = fpa_size_80;
    p_usw_scl_master[lchip]->fpa_size[SYS_SCL_KEY_HASH_VXLAN_V4_MODE1]          = CTC_FPA_KEY_SIZE_160;
    p_usw_scl_master[lchip]->fpa_size[SYS_SCL_KEY_HASH_VXLAN_UC_V6_MODE0]       = CTC_FPA_KEY_SIZE_320;
    p_usw_scl_master[lchip]->fpa_size[SYS_SCL_KEY_HASH_VXLAN_UC_V6_MODE1]       = CTC_FPA_KEY_SIZE_320;
    p_usw_scl_master[lchip]->fpa_size[SYS_SCL_KEY_HASH_VXLAN_MC_V6_MODE0]       = CTC_FPA_KEY_SIZE_320;
    p_usw_scl_master[lchip]->fpa_size[SYS_SCL_KEY_HASH_VXLAN_MC_V6_MODE1]       = CTC_FPA_KEY_SIZE_320;
    p_usw_scl_master[lchip]->fpa_size[SYS_SCL_KEY_HASH_WLAN_IPV4]               = CTC_FPA_KEY_SIZE_160;
    p_usw_scl_master[lchip]->fpa_size[SYS_SCL_KEY_HASH_WLAN_IPV6]               = CTC_FPA_KEY_SIZE_320;
    p_usw_scl_master[lchip]->fpa_size[SYS_SCL_KEY_HASH_WLAN_RMAC]               = CTC_FPA_KEY_SIZE_160;
    p_usw_scl_master[lchip]->fpa_size[SYS_SCL_KEY_HASH_WLAN_RMAC_RID]           = CTC_FPA_KEY_SIZE_160;
    p_usw_scl_master[lchip]->fpa_size[SYS_SCL_KEY_HASH_WLAN_STA_STATUS]         = CTC_FPA_KEY_SIZE_160;
    p_usw_scl_master[lchip]->fpa_size[SYS_SCL_KEY_HASH_WLAN_MC_STA_STATUS]      = CTC_FPA_KEY_SIZE_160;
    p_usw_scl_master[lchip]->fpa_size[SYS_SCL_KEY_HASH_WLAN_VLAN_FORWARD]       = CTC_FPA_KEY_SIZE_160;
    p_usw_scl_master[lchip]->fpa_size[SYS_SCL_KEY_HASH_WLAN_MACDA_FORWARD]      = CTC_FPA_KEY_SIZE_160;
    p_usw_scl_master[lchip]->fpa_size[SYS_SCL_KEY_HASH_TUNNEL_MPLS]             = fpa_size_80;
    p_usw_scl_master[lchip]->fpa_size[SYS_SCL_KEY_HASH_ECID]                    = CTC_FPA_KEY_SIZE_160;
    p_usw_scl_master[lchip]->fpa_size[SYS_SCL_KEY_HASH_ING_ECID]                = CTC_FPA_KEY_SIZE_160;
    p_usw_scl_master[lchip]->fpa_size[SYS_SCL_KEY_HASH_TRILL_UC]                = fpa_size_80;
    p_usw_scl_master[lchip]->fpa_size[SYS_SCL_KEY_HASH_TRILL_UC_RPF]            = fpa_size_80;
    p_usw_scl_master[lchip]->fpa_size[SYS_SCL_KEY_HASH_TRILL_MC]                = fpa_size_80;
    p_usw_scl_master[lchip]->fpa_size[SYS_SCL_KEY_HASH_TRILL_MC_RPF]            = fpa_size_80;
    p_usw_scl_master[lchip]->fpa_size[SYS_SCL_KEY_HASH_TRILL_MC_ADJ]            = fpa_size_80;
    p_usw_scl_master[lchip]->fpa_size[SYS_SCL_KEY_TCAM_UDF]                     = CTC_FPA_KEY_SIZE_160;
    p_usw_scl_master[lchip]->fpa_size[SYS_SCL_KEY_TCAM_UDF_EXT]                 = CTC_FPA_KEY_SIZE_320;
    p_usw_scl_master[lchip]->fpa_size[SYS_SCL_KEY_TCAM_UDF_QUAD]                = CTC_FPA_KEY_SIZE_640;
    p_usw_scl_master[lchip]->fpa_size[SYS_SCL_KEY_HASH_LP_GRP]                  = CTC_FPA_KEY_SIZE_80;
    p_usw_scl_master[lchip]->fpa_size[SYS_SCL_KEY_HASH_MD_ISOLATION_GRP]        = CTC_FPA_KEY_SIZE_80;
    p_usw_scl_master[lchip]->fpa_size[SYS_SCL_KEY_HASH_LOGIC_PORT]              = CTC_FPA_KEY_SIZE_80;
    p_usw_scl_master[lchip]->fpa_size[SYS_SCL_KEY_HASH_CID_ISOLATION_GRP]       = CTC_FPA_KEY_SIZE_80;

    p_usw_scl_master[lchip]->fpa = fpa_usw_create(lchip,
                                                  _sys_usw_scl_get_block_by_pe_fpa,
                                                  _sys_usw_scl_entry_move_hw_fpa,
                                                  sizeof(ctc_list_pointer_node_t));

    MALLOC_ZERO(MEM_SCL_MODULE,p_usw_scl_master[lchip]->fpa_block,sizeof(sys_scl_sw_block_t)*MCHIP_CAP(SYS_CAP_SCL_TCAM_NUM));
    if(NULL == p_usw_scl_master[lchip]->fpa_block)
    {
        SYS_SCL_DBG_OUT(CTC_DEBUG_LEVEL_ERROR, " No memory \n");
        return CTC_E_NO_MEMORY;
    }

    /* init each tcam block */
    for (loop = 0; loop < MCHIP_CAP(SYS_CAP_SCL_TCAM_NUM); loop++)
    {
        entry_cnt[CTC_FPA_KEY_SIZE_640] = (scl_tcam[loop] / 8)&0xFFF8;
        entry_cnt[CTC_FPA_KEY_SIZE_320] = (scl_tcam[loop]*3 / 8)&0xFFF4;
        entry_cnt[CTC_FPA_KEY_SIZE_160] = scl_tcam[loop] - entry_cnt[CTC_FPA_KEY_SIZE_320] - entry_cnt[CTC_FPA_KEY_SIZE_640];

        p_usw_scl_master[lchip]->fpa_block[loop].fpab.entry_count = scl_tcam[loop];
        p_usw_scl_master[lchip]->fpa_block[loop].fpab.free_count  = scl_tcam[loop];


        p_usw_scl_master[lchip]->fpa_block[loop].fpab.sub_entry_count[CTC_FPA_KEY_SIZE_640] = entry_cnt[CTC_FPA_KEY_SIZE_640] >> 3;
        p_usw_scl_master[lchip]->fpa_block[loop].fpab.sub_free_count[CTC_FPA_KEY_SIZE_640]  = entry_cnt[CTC_FPA_KEY_SIZE_640] >> 3;
        p_usw_scl_master[lchip]->fpa_block[loop].fpab.sub_rsv_count[CTC_FPA_KEY_SIZE_640]  = 0;
        p_usw_scl_master[lchip]->fpa_block[loop].fpab.start_offset[CTC_FPA_KEY_SIZE_640] = scl_tcam[loop] - entry_cnt[CTC_FPA_KEY_SIZE_640];


        p_usw_scl_master[lchip]->fpa_block[loop].fpab.start_offset[CTC_FPA_KEY_SIZE_320]    = entry_cnt[CTC_FPA_KEY_SIZE_160];
        p_usw_scl_master[lchip]->fpa_block[loop].fpab.sub_entry_count[CTC_FPA_KEY_SIZE_320] = entry_cnt[CTC_FPA_KEY_SIZE_320] >> 2;
        p_usw_scl_master[lchip]->fpa_block[loop].fpab.sub_free_count[CTC_FPA_KEY_SIZE_320]  = entry_cnt[CTC_FPA_KEY_SIZE_320] >> 2;
        p_usw_scl_master[lchip]->fpa_block[loop].fpab.sub_rsv_count[CTC_FPA_KEY_SIZE_320]  = 0;

        offset = 0;
        p_usw_scl_master[lchip]->fpa_block[loop].fpab.start_offset[CTC_FPA_KEY_SIZE_160]    = offset;
        p_usw_scl_master[lchip]->fpa_block[loop].fpab.sub_entry_count[CTC_FPA_KEY_SIZE_160] = entry_cnt[CTC_FPA_KEY_SIZE_160] >> 1;
        p_usw_scl_master[lchip]->fpa_block[loop].fpab.sub_free_count[CTC_FPA_KEY_SIZE_160]  = entry_cnt[CTC_FPA_KEY_SIZE_160] >> 1;
        p_usw_scl_master[lchip]->fpa_block[loop].fpab.sub_rsv_count[CTC_FPA_KEY_SIZE_160]   = 0;

        p_usw_scl_master[lchip]->fpa_block[loop].fpab.start_offset[CTC_FPA_KEY_SIZE_80]    = 0;
        p_usw_scl_master[lchip]->fpa_block[loop].fpab.sub_entry_count[CTC_FPA_KEY_SIZE_80] = 0;
        p_usw_scl_master[lchip]->fpa_block[loop].fpab.sub_free_count[CTC_FPA_KEY_SIZE_80]  = 0;
        p_usw_scl_master[lchip]->fpa_block[loop].fpab.sub_rsv_count[CTC_FPA_KEY_SIZE_80]   = 0;

        entry_size = sizeof(sys_scl_sw_entry_t*) * scl_tcam[loop];
        MALLOC_ZERO(MEM_SCL_MODULE, p_usw_scl_master[lchip]->fpa_block[loop].fpab.entries, entry_size);
        if (NULL == p_usw_scl_master[lchip]->fpa_block[loop].fpab.entries && entry_size)
        {
            SYS_SCL_DBG_OUT(CTC_DEBUG_LEVEL_ERROR, " No memory \n");
            return CTC_E_NO_MEMORY;

        }
    }

    return CTC_E_NONE;
}

#define __scl_warmboot_function__

int32
_sys_usw_scl_wb_mapping_group(uint8 lchip,sys_wb_scl_group_t* p_wb_scl_group, sys_scl_sw_group_t* p_scl_group, uint8 is_sync)
{
    if (is_sync)
    {
        p_wb_scl_group->group_id = p_scl_group->group_id;
        p_wb_scl_group->priority = p_scl_group->priority;
        p_wb_scl_group->type     = p_scl_group->type;
        p_wb_scl_group->gport    = p_scl_group->gport;
    }
    else
    {
        p_scl_group->group_id = p_wb_scl_group->group_id;
        p_scl_group->type     = p_wb_scl_group->type;
        p_scl_group->priority = p_wb_scl_group->priority;
        p_scl_group->gport    = p_wb_scl_group->gport;
		ctc_list_pointer_init(&(p_scl_group->entry_list));
    }
    return CTC_E_NONE;
}

int32
_sys_usw_scl_wb_sync_group_func(void* bucket_data, void* user_data)
{
    uint32 max_entry_num = 0;
    ctc_wb_data_t* p_wb_data = NULL;
    sys_scl_sw_group_t* p_scl_group = NULL;
    sys_wb_scl_group_t* p_wb_scl_group = NULL;
    uint8                    lchip = 0;

    p_scl_group = (sys_scl_sw_group_t*)bucket_data;
    p_wb_data = (ctc_wb_data_t*)user_data;

    max_entry_num = p_wb_data->buffer_len / sizeof(sys_wb_scl_group_t);
    p_wb_scl_group = (sys_wb_scl_group_t*)p_wb_data->buffer + p_wb_data->valid_cnt;
    sal_memset(p_wb_scl_group, 0, sizeof(sys_wb_scl_group_t));

    CTC_ERROR_RETURN(_sys_usw_scl_wb_mapping_group(lchip,p_wb_scl_group, p_scl_group, 1));
    if (++p_wb_data->valid_cnt == max_entry_num)
    {
        CTC_ERROR_RETURN(ctc_wb_add_entry(p_wb_data));
        p_wb_data->valid_cnt = 0;
    }

    return CTC_E_NONE;
}


int32
_sys_usw_scl_mapping_ad(void* ad, sys_scl_sw_igs_ad_t* temp_ad, uint8 is2temp, uint8 is_igs_hash, uint8 dir)
{
    uint8 ad_type = 0;

    CTC_PTR_VALID_CHECK(ad);
    CTC_PTR_VALID_CHECK(temp_ad);

    if (is2temp)
    {
        if (CTC_EGRESS == dir)
        {
            temp_ad->com.u1_type         = ((sys_scl_sw_egs_ad_t*)ad)->u1_type;
            temp_ad->is_service_policer  = ((sys_scl_sw_egs_ad_t*)ad)->is_service_policer;

            return CTC_E_NONE;
        }

        ad_type = ((sys_scl_sw_igs_ad0_t*)ad)->com.ad_type;
        sal_memcpy(&temp_ad->com,ad,sizeof(sys_scl_ad_com_t));
        temp_ad->vlan_profile_id = 0x3FF;
        temp_ad->acl_profile_id = 0xFF;
        switch (ad_type)
        {
            case SYS_SCL_SW_AD_TYPE_IGS_0:
                break;

            case SYS_SCL_SW_AD_TYPE_IGS_1:
                temp_ad->nexthop_id = ((sys_scl_sw_igs_ad1_t*)ad)->nexthop_id;
                temp_ad->bind_nh = ((sys_scl_sw_igs_ad1_t*)ad)->bind_nh;
                temp_ad->fwd_type = ((sys_scl_sw_igs_ad1_t*)ad)->fwd_type;
                break;

            case SYS_SCL_SW_AD_TYPE_IGS_2:
                temp_ad->vlan_profile_id = ((sys_scl_sw_igs_ad2_t*)ad)->vlan_profile_id;
                temp_ad->vlan_edit = ((sys_scl_sw_igs_ad2_t*)ad)->vlan_edit;
                break;

            case SYS_SCL_SW_AD_TYPE_IGS_3:
                temp_ad->inner_rmac_index = ((sys_scl_sw_igs_ad3_t*)ad)->inner_rmac_index;
                break;

            case SYS_SCL_SW_AD_TYPE_IGS_4:
                sal_memcpy(temp_ad, ad, CTC_OFFSET_OF(sys_scl_sw_igs_ad_t, calc_key_len));
                break;
        }
    }
    else
    {
        if (CTC_EGRESS == dir)
        {
            ((sys_scl_sw_egs_ad_t*)ad)->u1_type              = temp_ad->com.u1_type;
            ((sys_scl_sw_egs_ad_t*)ad)->is_service_policer   = temp_ad->is_service_policer;
            return CTC_E_NONE;
        }

        ad_type = temp_ad->com.ad_type;
        sal_memcpy(ad, &temp_ad->com,sizeof(sys_scl_ad_com_t));
        switch (ad_type)
        {
            case SYS_SCL_SW_AD_TYPE_IGS_0:
                if (is_igs_hash && (CTC_WB_STATUS(temp_ad->com.lchip) != CTC_WB_STATUS_RELOADING))
                {
                    ((sys_scl_sw_igs_ad0_t*)ad)->action = temp_ad->action;
                }
                break;

            case SYS_SCL_SW_AD_TYPE_IGS_1:
                ((sys_scl_sw_igs_ad1_t*)ad)->nexthop_id = temp_ad->nexthop_id;
                ((sys_scl_sw_igs_ad1_t*)ad)->bind_nh = temp_ad->bind_nh;
                ((sys_scl_sw_igs_ad1_t*)ad)->fwd_type = temp_ad->fwd_type;
                if (is_igs_hash && (CTC_WB_STATUS(temp_ad->com.lchip) != CTC_WB_STATUS_RELOADING))
                {
                    ((sys_scl_sw_igs_ad1_t*)ad)->action = temp_ad->action;
                }
                break;

            case SYS_SCL_SW_AD_TYPE_IGS_2:
                ((sys_scl_sw_igs_ad2_t*)ad)->vlan_profile_id = temp_ad->vlan_profile_id;
                ((sys_scl_sw_igs_ad2_t*)ad)->vlan_edit = temp_ad->vlan_edit;
                if (is_igs_hash && (CTC_WB_STATUS(temp_ad->com.lchip) != CTC_WB_STATUS_RELOADING) )
                {
                    ((sys_scl_sw_igs_ad2_t*)ad)->action = temp_ad->action;
                }
                break;

            case SYS_SCL_SW_AD_TYPE_IGS_3:
                ((sys_scl_sw_igs_ad3_t*)ad)->inner_rmac_index = temp_ad->inner_rmac_index;
                if (is_igs_hash && (CTC_WB_STATUS(temp_ad->com.lchip) != CTC_WB_STATUS_RELOADING))
                {
                    ((sys_scl_sw_igs_ad3_t*)ad)->action = temp_ad->action;
                }
                break;

            case SYS_SCL_SW_AD_TYPE_IGS_4:
                sal_memcpy(ad, temp_ad, CTC_OFFSET_OF(sys_scl_sw_igs_ad_t, calc_key_len));
                if (is_igs_hash && (CTC_WB_STATUS(temp_ad->com.lchip) != CTC_WB_STATUS_RELOADING) )
                {
                    ((sys_scl_sw_igs_ad_t*)ad)->action = temp_ad->action;
                }
                break;
        }
    }

    return CTC_E_NONE;
}

int32
_sys_usw_scl_wb_mapping_egs_entry(uint8 lchip, sys_wb_scl_egs_entry_t* p_wb_scl_egs_hash_entry, sys_scl_sw_entry_t* p_scl_entry, uint8 is_sync, uint8 is_default)
{
    uint8  hash_uninstall = 0;
    sys_scl_flexed_key_t* p_scl_flex_key = NULL;
    sys_scl_sw_igs_ad_t temp_ad;
    sys_scl_sw_block_t*         pb = NULL;

    sal_memset(&temp_ad, 0, sizeof(sys_scl_sw_igs_ad_t));
    if (is_sync)
    {
        _sys_usw_scl_mapping_ad(p_scl_entry->u.ad, &temp_ad, 1, 0, p_scl_entry->direction);
        p_wb_scl_egs_hash_entry->entry_id             = p_scl_entry->entry_id;
        p_wb_scl_egs_hash_entry->key_type             = p_scl_entry->key_type;
        p_wb_scl_egs_hash_entry->action_type          = p_scl_entry->action_type;
        p_wb_scl_egs_hash_entry->u1_type              = temp_ad.com.u1_type;
        p_wb_scl_egs_hash_entry->is_service_policer   = temp_ad.is_service_policer;
        p_wb_scl_egs_hash_entry->resolve_conflict     = p_scl_entry->resolve_conflict;
        p_wb_scl_egs_hash_entry->hash_valid           = p_scl_entry->hash_valid;
        SYS_SCL_COPY_DB_TO_WB(p_wb_scl_egs_hash_entry->key_index, p_scl_entry->key_index);
        p_wb_scl_egs_hash_entry->key_bmp              = p_scl_entry->key_bmp;
        p_wb_scl_egs_hash_entry->group_id             = p_scl_entry->group_id;
        p_wb_scl_egs_hash_entry->is_xkey              = p_scl_entry->is_xkey;
        p_wb_scl_egs_hash_entry->uninstall            = p_scl_entry->uninstall;
        p_wb_scl_egs_hash_entry->priority = 0;
        if (p_scl_entry->resolve_conflict)
        {
            pb = &p_usw_scl_master[lchip]->fpa_block[SCL_ENCODE_BLOCK_ID(p_scl_entry->direction, p_scl_entry->group_priority)];
            SYS_SCL_COPY_DB_TO_WB(p_wb_scl_egs_hash_entry->priority, pb->fpab.entries[p_scl_entry->key_index]->priority);
        }
        sal_memcpy(p_wb_scl_egs_hash_entry->action_bmp, p_scl_entry->action_bmp, sizeof(p_scl_entry->action_bmp));
    }
    else
    {
        uint32 key_id = 0;
        uint32 act_id = 0;
        uint32 cmd;
        uint32 entry_size = 0;
        ds_t temp_ds_data;
        ds_t temp_ds_mask;
        tbl_entry_t tcam_entry;
        uint8  count_size = 0;
        sys_scl_sw_group_t* pg = NULL;
        void* p_malloc_ad = NULL;
        uint8 fpa_size = 0;
        uint8 igs_hash_key = 0;
        uint16 pp_bmp = 0;
        uint8 pp_base =  sys_usw_vchip_get_pp_base(lchip);
        uint8 size[SYS_SCL_SW_AD_TYPE_MAX] = {CTC_OFFSET_OF(sys_scl_sw_igs_ad0_t, calc_key_len),
                                                 CTC_OFFSET_OF(sys_scl_sw_igs_ad1_t, calc_key_len),
                                                 CTC_OFFSET_OF(sys_scl_sw_igs_ad2_t, calc_key_len),
                                                 CTC_OFFSET_OF(sys_scl_sw_igs_ad3_t, calc_key_len),
                                                 CTC_OFFSET_OF(sys_scl_sw_igs_ad_t, calc_key_len),
                                                 sizeof(sys_scl_sw_egs_ad_t)};

        p_scl_entry->key_type           = p_wb_scl_egs_hash_entry->key_type;
        p_scl_entry->entry_id           = p_wb_scl_egs_hash_entry->entry_id;
        p_scl_entry->resolve_conflict   = p_wb_scl_egs_hash_entry->resolve_conflict;
        p_scl_entry->key_index          = SYS_SCL_WB_DATA(p_wb_scl_egs_hash_entry->key_index);
        p_scl_entry->key_bmp            = p_wb_scl_egs_hash_entry->key_bmp;
        p_scl_entry->direction          = CTC_EGRESS;
        p_scl_entry->hash_valid         = p_wb_scl_egs_hash_entry->hash_valid;
        p_scl_entry->is_xkey            = p_wb_scl_egs_hash_entry->is_xkey;
        p_scl_entry->action_type        = p_wb_scl_egs_hash_entry->action_type;
        p_scl_entry->uninstall          = p_wb_scl_egs_hash_entry->uninstall;
        p_scl_entry->group_id           = p_wb_scl_egs_hash_entry->group_id;
        temp_ad.com.action_type         = p_wb_scl_egs_hash_entry->action_type;
        temp_ad.com.u1_type             = p_wb_scl_egs_hash_entry->u1_type;
        temp_ad.com.ad_index            = SYS_SCL_WB_DATA(p_wb_scl_egs_hash_entry->key_index);
        temp_ad.is_service_policer      = p_wb_scl_egs_hash_entry->is_service_policer;
        temp_ad.com.lchip               = lchip;
        temp_ad.com.ad_type             = SYS_SCL_SW_AD_TYPE_EGS_0;
        temp_ad.vlan_profile_id         = 0x3FF;
        temp_ad.acl_profile_id          = 0xFF;
        sal_memset(&temp_ds_data, 0, sizeof(ds_t));
        sal_memset(&temp_ds_mask, 0, sizeof(ds_t));

        sal_memcpy(p_scl_entry->action_bmp, p_wb_scl_egs_hash_entry->action_bmp, sizeof(p_scl_entry->action_bmp));

        _sys_usw_scl_get_group_by_gid(lchip,p_wb_scl_egs_hash_entry->group_id, &pg);
        p_scl_entry->group_priority = pg->priority;
        _sys_usw_scl_get_table_id(lchip, pg->priority, p_scl_entry, &key_id, &act_id);
        cmd = DRV_IOR(key_id , DRV_ENTRY_FLAG);
        temp_ad.com.ad_index = p_scl_entry->key_index;
        if (p_scl_entry->resolve_conflict)
        {
            tcam_entry.data_entry = temp_ds_data;
            tcam_entry.mask_entry = temp_ds_mask;
            DRV_IOCTL(lchip,  p_scl_entry->key_index , DRV_CMD_BMP_EN(cmd, MCHIP_FEATURE_PP_EN(lchip,CTC_FEATURE_SCL)), &tcam_entry);
        }
        else
        {
            DRV_IOCTL(lchip, p_scl_entry->key_index , DRV_CMD_BMP_EN(cmd, MCHIP_FEATURE_PP_EN(lchip,CTC_FEATURE_SCL)), &temp_ds_data);
        }

        /*Only hash uninstalled entry need to clear valid bit*/
        hash_uninstall = p_scl_entry->uninstall;
        if(hash_uninstall && p_scl_entry->hash_valid)
        {
            int32 ret = 0;
            drv_acc_in_t in;
            drv_acc_out_t out;
            uint32 pu32[MAX_ENTRY_WORD] = { 0 };

            sal_memset(&in, 0, sizeof(in));
            sal_memset(&out, 0, sizeof(out));

            drv_set_warmboot_status(lchip, DRV_WB_STATUS_DONE);
            in.type = DRV_ACC_TYPE_ADD;
            in.op_type = DRV_ACC_OP_BY_INDEX;
            in.tbl_id = key_id;
            drv_acc_get_hash_module(lchip,in.tbl_id, &in.module);
            in.data   = &pu32;
            in.index  = p_scl_entry->key_index;
            in.oper_bmp = DRV_ACC_BMP_EN(MCHIP_FEATURE_PP_EN(lchip, CTC_FEATURE_SCL));
            ret = drv_acc_api(lchip, &in, &out);
            drv_set_warmboot_status(lchip, DRV_WB_STATUS_RELOADING);
            return ret;
        }
        
        CTC_ERROR_RETURN(_sys_usw_scl_get_flex_key_node(lchip, p_scl_entry, &p_scl_flex_key));
        if(p_scl_flex_key)
        {
            p_scl_flex_key->entry_count++;
        }

        CTC_ERROR_RETURN(sys_usw_ftm_query_table_entry_size(lchip, key_id, &entry_size));
        count_size = entry_size / SCL_KEY_USW_SIZE_80;
        count_size =    !p_scl_entry->resolve_conflict ? count_size :
                        p_scl_entry->direction == CTC_INGRESS ? count_size : (count_size*2);
        if ((!SCL_ENTRY_IS_TCAM(p_scl_entry->key_type) && !p_scl_entry->resolve_conflict) || (p_scl_entry->resolve_conflict && DRV_FROM_TMM(lchip)))
        {
            p_usw_scl_master[lchip]->entry_count[p_scl_entry->group_priority][p_scl_entry->action_type] += count_size;
        }

         MALLOC_ZERO(MEM_SCL_MODULE, p_malloc_ad, size[temp_ad.com.ad_type]);
         if (!p_malloc_ad)
         {
                return  CTC_E_NO_MEMORY;
         }
         igs_hash_key = !(SCL_ENTRY_IS_TCAM(p_scl_entry->key_type) || p_scl_entry->resolve_conflict) && (SYS_SCL_ACTION_EGRESS != p_scl_entry->action_type);
         _sys_usw_scl_mapping_ad(p_malloc_ad, &temp_ad, 0, igs_hash_key, p_scl_entry->direction);

         p_scl_entry->u.ad = p_malloc_ad;

        /* for hash entry */
        if (!p_scl_entry->resolve_conflict && SYS_SCL_IS_INNER_ENTRY(p_scl_entry->entry_id))
        {
            sys_scl_hash_key_entry_t* hash_entry;               /* when do hash insert, the data to inserted must be a pointer */

            MALLOC_ZERO(MEM_SCL_MODULE, hash_entry, sizeof(sys_scl_hash_key_entry_t));
            if (NULL == hash_entry)
            {
                SYS_SCL_DBG_OUT(CTC_DEBUG_LEVEL_ERROR, " No memory \n");
                return CTC_E_NO_MEMORY;
            }
            hash_entry->action_type =p_wb_scl_egs_hash_entry->action_type;
            hash_entry->entry_id = p_wb_scl_egs_hash_entry->entry_id;

            hash_entry->scl_id = pg->priority;
            hash_entry->key_index = p_scl_entry->key_index;

            /* add to hash by key */
            if (NULL == ctc_hash_insert(p_usw_scl_master[lchip]->hash_key_entry, hash_entry))
            {
                SYS_SCL_DBG_OUT(CTC_DEBUG_LEVEL_ERROR, " [SCL] Hash insert fail\n");
                mem_free(hash_entry);
                return CTC_E_NO_MEMORY;
            }
        }
        else if(p_scl_entry->resolve_conflict)
        {
            sys_scl_sw_tcam_entry_t* pe_tcam = NULL;
            MALLOC_ZERO(MEM_SCL_MODULE, pe_tcam, sizeof(sys_scl_sw_tcam_entry_t));
            if (NULL == pe_tcam)
            {
                SYS_SCL_DBG_OUT(CTC_DEBUG_LEVEL_ERROR, " No memory \n");
                return CTC_E_NO_MEMORY;

            }
            pe_tcam->fpae.entry_id = p_wb_scl_egs_hash_entry->entry_id;
            pe_tcam->fpae.offset_a = p_scl_entry->key_index;
            pe_tcam->fpae.priority = p_wb_scl_egs_hash_entry->priority;
            SYS_SCL_ENCODE_XKEY_FPA_SIZE(p_scl_flex_key, p_wb_scl_egs_hash_entry, fpa_size)
            pe_tcam->fpae.step = SYS_SCL_GET_STEP(p_usw_scl_master[lchip]->fpa_size[p_wb_scl_egs_hash_entry->key_type]);
            pe_tcam->fpae.flag =1;
            pe_tcam->entry = p_scl_entry;
            pb = &p_usw_scl_master[lchip]->fpa_block[SCL_ENCODE_BLOCK_ID(p_scl_entry->direction, pg->priority)];
            pb->fpab.entries[p_scl_entry->key_index] = &pe_tcam->fpae;
        }

        /* for inner entry need to restore entry-id-opf */
        if(SCL_INNER_ENTRY_ID(p_scl_entry->entry_id))
        {
            sys_usw_opf_t opf;
            sal_memset(&opf, 0, sizeof(sys_usw_opf_t));
            opf.pool_index = 0;
            opf.pool_type  = p_usw_scl_master[pp_base]->opf_type_entry_id;

            sys_usw_opf_alloc_offset_from_position(pp_base, &opf, 1, (p_scl_entry->entry_id - SYS_SCL_MIN_INNER_ENTRY_ID));
            if (p_wb_scl_egs_hash_entry->resolve_conflict)
            {
                sys_scl_tcam_entry_key_t* tcam_entry;               /* when do hash insert, the data to inserted must be a pointer */
                uint8 loop = 0;
                tbl_entry_t          entry;
                uint32      hw_key_index  = 0;
                uint32      hw_ad_index   = 0;

                MALLOC_ZERO(MEM_SCL_MODULE, tcam_entry, sizeof(sys_scl_tcam_entry_key_t));
                if (NULL == tcam_entry)
                {
                    SYS_SCL_DBG_OUT(CTC_DEBUG_LEVEL_ERROR, " No memory \n");
                    return CTC_E_NO_MEMORY;
                }
                entry.data_entry = tcam_entry->key;
                entry.mask_entry = tcam_entry->mask;
                cmd = DRV_IOR(key_id, DRV_ENTRY_FLAG);
                _sys_usw_scl_get_index(lchip, key_id, p_scl_entry, &hw_key_index, &hw_ad_index);
                DRV_IOCTL(lchip, hw_key_index, DRV_CMD_BMP_EN(cmd, MCHIP_FEATURE_PP_EN(lchip,CTC_FEATURE_SCL)), &entry);

                for(loop = 0; loop < SYS_SCL_MAX_KEY_SIZE_IN_WORD; loop++)
                {
                    tcam_entry->key[loop] = tcam_entry->key[loop] & tcam_entry->mask[loop];
                }
                tcam_entry->scl_id = pg->priority;
                tcam_entry->p_entry = p_scl_entry;

                /* add to hash by key */
                if (NULL == ctc_hash_insert(p_usw_scl_master[lchip]->tcam_entry_by_key, tcam_entry))
                {
                    mem_free(tcam_entry);
                    SYS_SCL_DBG_OUT(CTC_DEBUG_LEVEL_ERROR, " [SCL] Hash insert fail\n");
                    return CTC_E_NO_MEMORY;
                }
            }
        }
        if(DRV_FROM_AT(lchip) && MCHIP_FEATURE_PP_EN(lchip, CTC_FEATURE_SCL))
        {
            CTC_BIT_SET(pp_bmp,(lchip - SYS_PP_BASE(lchip)));
            if(SYS_SCL_IS_ENTRY_HASH_BITMAP(p_scl_entry->entry_id,p_wb_scl_egs_hash_entry->group_id) ||
                   p_scl_entry->entry_id <= CTC_SCL_MAX_USER_ENTRY_ID)
            {
                sys_usw_scl_add_entry_hash_inner(SYS_PP_BASE(lchip), p_scl_entry->entry_id,pp_bmp);
            }
        }

        /* add to group entry list's head */
        ctc_list_pointer_insert_head(&(pg->entry_list), &(p_scl_entry->head));

    }

    return CTC_E_NONE;
}


int32
_sys_usw_scl_wb_sync_egs_hash_entry_func(void* bucket_data, void* user_data)
{
    uint32 max_entry_num = 0;
    sys_scl_sw_entry_t* p_scl_entry    = NULL;
    sys_wb_scl_egs_entry_t*   p_wb_scl_egs_hash_entry = NULL;
    ctc_wb_data_t*           p_wb_data      = NULL;
    sys_scl_flexed_key_t* p_scl_flex_key = NULL;
    sys_scl_sw_block_t*      p_block = NULL;
    uint8                    lchip = 0;
    uint8                    is_default;

    p_scl_entry = (sys_scl_sw_entry_t*)bucket_data;
    p_wb_data   = (ctc_wb_data_t*)(((sys_scl_traverse_data_t*)user_data)->data0);
    p_block   = (sys_scl_sw_block_t*)(((sys_scl_traverse_data_t*)user_data)->data1);
    lchip     = ((sys_scl_traverse_data_t*)user_data)->value0;
    is_default = ((sys_scl_traverse_data_t*)user_data)->value1;

    p_wb_scl_egs_hash_entry = (sys_wb_scl_egs_entry_t*)p_wb_data->buffer + p_wb_data->valid_cnt;
    sal_memset(p_wb_scl_egs_hash_entry, 0, sizeof(sys_wb_scl_egs_entry_t));

    max_entry_num = p_wb_data->buffer_len / sizeof(sys_wb_scl_egs_entry_t);


    if(SYS_SCL_ACTION_EGRESS != p_scl_entry->action_type)
    {
        return CTC_E_NONE;
    }

    if (p_scl_entry->is_buffer)
    {
         /* uninstall entry not sync, but need to update fpa count for tcam entry
          * need to clear valid bit after restore,so need to store key index for hash entry
          */
        if (!is_default && (SCL_ENTRY_IS_TCAM(p_scl_entry->key_type) || (p_scl_entry->resolve_conflict)))
        {
            uint8 fpa_size =0;
            p_scl_flex_key = (sys_scl_flexed_key_t*)p_scl_entry->u.temp_entry->fk;
            SYS_SCL_ENCODE_XKEY_FPA_SIZE(p_scl_flex_key, p_scl_entry, fpa_size)
            if (p_scl_flex_key && p_scl_flex_key->is_xkey && !p_scl_flex_key->is_replace)
            {
                fpa_size = fpa_size+1;
            }

            (p_block[SCL_ENCODE_BLOCK_ID(p_scl_entry->direction, p_scl_entry->group_priority)].fpab.free_count) += (SYS_SCL_GET_STEP(fpa_size));
            (p_block[SCL_ENCODE_BLOCK_ID(p_scl_entry->direction, p_scl_entry->group_priority)].fpab.sub_free_count[fpa_size])++;

            return CTC_E_NONE;
        }
        else if(is_default || p_scl_entry->hash_valid == 0)
        {
            return CTC_E_NONE;
        }
    }


    CTC_ERROR_RETURN(_sys_usw_scl_wb_mapping_egs_entry(lchip, p_wb_scl_egs_hash_entry, p_scl_entry, 1, is_default));

    if (++p_wb_data->valid_cnt == max_entry_num)
    {
        CTC_ERROR_RETURN(ctc_wb_add_entry(p_wb_data));
        p_wb_data->valid_cnt = 0;
    }
    return CTC_E_NONE;
}
int32
_sys_usw_scl_wb_mapping_igs_tcam_entry(uint8 lchip, sys_wb_scl_igs_tcam_entry_t* p_wb_scl_igs_tcam_entry, sys_scl_sw_entry_tcam_t* p_scl_tcam_entry, uint8 is_sync, uint8 is_default)
{
    sys_scl_flexed_key_t* p_scl_flex_key = NULL;
    sys_scl_sw_block_t*         pb = NULL;
    sys_scl_sw_igs_ad_t temp_ad;
    sys_scl_action_acl_t* p_acl = NULL;

    sal_memset(&temp_ad, 0, sizeof(sys_scl_sw_igs_ad_t));
    if (is_sync)
    {
        _sys_usw_scl_mapping_ad(p_scl_tcam_entry->he.u.ad, &temp_ad, 1, 0, p_scl_tcam_entry->he.direction);
        p_wb_scl_igs_tcam_entry->entry_id             = p_scl_tcam_entry->he.entry_id;
        p_wb_scl_igs_tcam_entry->key_type             = p_scl_tcam_entry->he.key_type;
        p_wb_scl_igs_tcam_entry->userid_bmp           = temp_ad.com.userid_bmp;
        p_wb_scl_igs_tcam_entry->key_bmp              = p_scl_tcam_entry->he.key_bmp;
        p_wb_scl_igs_tcam_entry->l3_type              = p_scl_tcam_entry->he.l3_type;
        p_wb_scl_igs_tcam_entry->l4_type              = p_scl_tcam_entry->he.l4_type;
        p_wb_scl_igs_tcam_entry->is_xkey              = p_scl_tcam_entry->he.is_xkey;
        p_wb_scl_igs_tcam_entry->group_id             = p_scl_tcam_entry->he.group_id;
        p_wb_scl_igs_tcam_entry->u1_type              = temp_ad.com.u1_type;
        p_wb_scl_igs_tcam_entry->u2_type              = temp_ad.com.u2_type;
        p_wb_scl_igs_tcam_entry->u3_type              = temp_ad.com.u3_type;
        p_wb_scl_igs_tcam_entry->u4_type              = temp_ad.com.u4_type;
        p_wb_scl_igs_tcam_entry->u5_type              = temp_ad.com.u5_type;
        p_wb_scl_igs_tcam_entry->is_service_policer   = temp_ad.is_service_policer;
        p_wb_scl_igs_tcam_entry->bind_nh              = temp_ad.bind_nh;
        p_wb_scl_igs_tcam_entry->fwd_bmp              = temp_ad.com.fwd_bmp;
        p_wb_scl_igs_tcam_entry->action_type          = p_scl_tcam_entry->he.action_type;
        p_wb_scl_igs_tcam_entry->fwd_type             = temp_ad.fwd_type;
        p_wb_scl_igs_tcam_entry->ad_type              = temp_ad.com.ad_type;
        p_wb_scl_igs_tcam_entry->ether_type_valid     =p_scl_tcam_entry->ether_type_valid;

        p_wb_scl_igs_tcam_entry->acl_profile_valid = 0;
        if(temp_ad.acl_profile)
        {
            p_wb_scl_igs_tcam_entry->acl_profile_valid = 1;
        }
        p_wb_scl_igs_tcam_entry->service_id           = temp_ad.service_id;

        SYS_SCL_COPY_DB_TO_WB(p_wb_scl_igs_tcam_entry->key_index, p_scl_tcam_entry->he.key_index);
        p_wb_scl_igs_tcam_entry->nexthop_id           = temp_ad.nexthop_id;

        pb = &p_usw_scl_master[lchip]->fpa_block[SCL_ENCODE_BLOCK_ID(p_scl_tcam_entry->he.direction, p_scl_tcam_entry->he.group_priority)];
        SYS_SCL_COPY_DB_TO_WB(p_wb_scl_igs_tcam_entry->priority, pb->fpab.entries[p_scl_tcam_entry->he.key_index]->priority);
        p_wb_scl_igs_tcam_entry->l2_type              = p_scl_tcam_entry->l2_type;
        p_wb_scl_igs_tcam_entry->l4_user_type         = p_scl_tcam_entry->l4_user_type;
        p_wb_scl_igs_tcam_entry->key_l4_port_mode     = p_scl_tcam_entry->key_l4_port_mode;
        p_wb_scl_igs_tcam_entry->ether_type_index     = p_scl_tcam_entry->ether_type_index;
        p_wb_scl_igs_tcam_entry->mac_key_vlan_mode    = p_scl_tcam_entry->mac_key_vlan_mode;
        p_wb_scl_igs_tcam_entry->mac_key_macda_mode   = p_scl_tcam_entry->mac_key_macda_mode;
        sal_memcpy(p_wb_scl_igs_tcam_entry->action_bmp, p_scl_tcam_entry->he.action_bmp, sizeof(p_scl_tcam_entry->he.action_bmp));
    }
    else
    {
        uint32 key_id = 0;
        uint32 act_id = 0;
        uint32 hw_key_index = 0;
        uint32 hw_ad_index= 0;
        uint32 cmd;
        sys_scl_action_acl_t acl;
        sys_scl_sw_group_t* pg = NULL;
        void *temp_vlan_xlate = NULL;
        uint32* temp_ds = NULL;
        uint8 vlan_edit_profile_id = 0;
        sys_scl_sp_vlan_edit_t* p_sp_vlan_edit = NULL;
        tbl_entry_t tcam_entry;
        ds_t tempds_key = {0};
        ds_t tempds_ad = {0};
        ds_t tempds_mask = {0} ;
        ds_t action_buffer = {0};
        uint8 vlan_action_valid;
        void* p_action_buffer = action_buffer;
        sys_scl_sp_vlan_edit_t sp_vlan_edit;
        uint8 fpa_size = 0;
        uint8 igs_hash_key = 0;
        uint8 ether_type_index = 0;
        void* p_malloc_tcam_ad = NULL;
        uint16 pp_bmp = 0;
        uint8 pp_base =  sys_usw_vchip_get_pp_base(lchip);
        mac_addr_t inner_rmac;
        uint16 rmac_index = 0;
        uint8 size[SYS_SCL_SW_AD_TYPE_MAX] = {CTC_OFFSET_OF(sys_scl_sw_igs_ad0_t, calc_key_len),
                                                 CTC_OFFSET_OF(sys_scl_sw_igs_ad1_t, calc_key_len),
                                                 CTC_OFFSET_OF(sys_scl_sw_igs_ad2_t, calc_key_len),
                                                 CTC_OFFSET_OF(sys_scl_sw_igs_ad3_t, calc_key_len),
                                                 CTC_OFFSET_OF(sys_scl_sw_igs_ad_t, calc_key_len),
                                                 sizeof(sys_scl_sw_egs_ad_t)};
        sys_scl_sw_tcam_entry_t* pe_tcam = NULL;
        sal_memset(&tcam_entry, 0, sizeof(tbl_entry_t));
        sal_memset(&tempds_ad, 0, sizeof(ds_t));
        sal_memset(&tempds_mask, 0, sizeof(ds_t));
        sal_memset(&tempds_key, 0, sizeof(ds_t));
        p_scl_tcam_entry->l2_type                = p_wb_scl_igs_tcam_entry->l2_type;
        p_scl_tcam_entry->l4_user_type           = p_wb_scl_igs_tcam_entry->l4_user_type;
        p_scl_tcam_entry->mac_key_vlan_mode      = p_wb_scl_igs_tcam_entry->mac_key_vlan_mode;
        p_scl_tcam_entry->mac_key_macda_mode     = p_wb_scl_igs_tcam_entry->mac_key_macda_mode;
        p_scl_tcam_entry->key_l4_port_mode       = p_wb_scl_igs_tcam_entry->key_l4_port_mode;
        p_scl_tcam_entry->ether_type_index       = p_wb_scl_igs_tcam_entry->ether_type_index;
        p_scl_tcam_entry->he.entry_id            = p_wb_scl_igs_tcam_entry->entry_id;
        p_scl_tcam_entry->he.key_type            = p_wb_scl_igs_tcam_entry->key_type;
        p_scl_tcam_entry->he.l3_type             = p_wb_scl_igs_tcam_entry->l3_type;
        p_scl_tcam_entry->he.l4_type             = p_wb_scl_igs_tcam_entry->l4_type;
        p_scl_tcam_entry->he.key_bmp             = p_wb_scl_igs_tcam_entry->key_bmp;
        p_scl_tcam_entry->he.action_type         = p_wb_scl_igs_tcam_entry->action_type;
        p_scl_tcam_entry->ether_type_valid       = p_wb_scl_igs_tcam_entry->ether_type_valid;
        p_scl_tcam_entry->he.key_index           = SYS_SCL_WB_DATA(p_wb_scl_igs_tcam_entry->key_index);
        p_scl_tcam_entry->he.is_xkey             = p_wb_scl_igs_tcam_entry->is_xkey;
        p_scl_tcam_entry->he.direction           = CTC_INGRESS;
        p_scl_tcam_entry->he.group_id            = p_wb_scl_igs_tcam_entry->group_id;
        temp_ad.acl_profile_id                   = 0xFF;
        temp_ad.com.u1_type                      = p_wb_scl_igs_tcam_entry->u1_type;
        temp_ad.com.u2_type                      = p_wb_scl_igs_tcam_entry->u2_type;
        temp_ad.com.u3_type                      = p_wb_scl_igs_tcam_entry->u3_type;
        temp_ad.com.u4_type                      = p_wb_scl_igs_tcam_entry->u4_type;
        temp_ad.com.u5_type                      = p_wb_scl_igs_tcam_entry->u5_type;
        temp_ad.com.userid_bmp                   = p_wb_scl_igs_tcam_entry->userid_bmp;
        temp_ad.is_service_policer               = p_wb_scl_igs_tcam_entry->is_service_policer;
        temp_ad.bind_nh                          = p_wb_scl_igs_tcam_entry->bind_nh;
        temp_ad.com.action_type                  = p_wb_scl_igs_tcam_entry->action_type;
        temp_ad.com.fwd_bmp                      = p_wb_scl_igs_tcam_entry->fwd_bmp;
        temp_ad.com.ad_type                      = p_wb_scl_igs_tcam_entry->ad_type;
        temp_ad.service_id                       = p_wb_scl_igs_tcam_entry->service_id;
        temp_ad.nexthop_id                       = p_wb_scl_igs_tcam_entry->nexthop_id;
        temp_ad.fwd_type                         = p_wb_scl_igs_tcam_entry->fwd_type;

        sal_memcpy(p_scl_tcam_entry->he.action_bmp, p_wb_scl_igs_tcam_entry->action_bmp, sizeof(p_wb_scl_igs_tcam_entry->action_bmp));
        CTC_ERROR_RETURN(_sys_usw_scl_get_flex_key_node(lchip,  &p_scl_tcam_entry->he, &p_scl_flex_key));
        if(p_scl_flex_key)
        {
            p_scl_flex_key->entry_count++;
        }

        if(p_scl_tcam_entry->ether_type_valid)
        {
            uint16 ether_type = 0;
            ether_type_index = p_scl_tcam_entry->ether_type_index;
            if(DRV_FROM_TMM(lchip))
            {
                UserIdEtherTypeCompressCam_m cam_cethertype;
                cmd = DRV_IOR(UserIdEtherTypeCompressCam_t, DRV_ENTRY_FLAG);
                CTC_ERROR_RETURN(DRV_IOCTL(lchip, p_scl_tcam_entry->ether_type_index, DRV_CMD_BMP_EN(cmd, MCHIP_FEATURE_PP_EN(lchip,CTC_FEATURE_SCL)), &cam_cethertype));
                ether_type = GetUserIdEtherTypeCompressCam(V,etherType_f, &cam_cethertype);
            }
            else
            {
                EtherTypeCompressCam_m       cam_cethertype;
                cmd = DRV_IOR(EtherTypeCompressCam_t, DRV_ENTRY_FLAG);
                CTC_ERROR_RETURN(DRV_IOCTL(lchip,p_scl_tcam_entry->ether_type_index, DRV_CMD_BMP_EN(cmd, MCHIP_FEATURE_PP_EN(lchip,CTC_FEATURE_SCL)), &cam_cethertype));
                ether_type = GetEtherTypeCompressCam(V,etherType_f, &cam_cethertype);
            }
            CTC_ERROR_RETURN(MCHIP_SCL(lchip)->add_compress_ether_type(lchip, ether_type, 0, NULL,&ether_type_index));
        }

        _sys_usw_scl_get_group_by_gid(lchip,p_scl_tcam_entry->he.group_id, &pg);
        p_scl_tcam_entry->he.group_priority    = pg->priority;
        _sys_usw_scl_get_table_id(lchip,pg->priority, &p_scl_tcam_entry->he, &key_id, &act_id);
        _sys_usw_scl_get_index(lchip, key_id, &p_scl_tcam_entry->he, &hw_key_index, &hw_ad_index);
        cmd = DRV_IOR(act_id, DRV_ENTRY_FLAG);
        DRV_IOCTL(lchip,hw_ad_index, DRV_CMD_BMP_EN(cmd, MCHIP_FEATURE_PP_EN(lchip,CTC_FEATURE_SCL)), &tempds_ad);
        temp_ad.com.ad_index = hw_ad_index;

        tcam_entry.data_entry = tempds_key;
        tcam_entry.mask_entry = tempds_mask;
        cmd = DRV_IOR(key_id , DRV_ENTRY_FLAG);
        DRV_IOCTL(lchip,hw_key_index, DRV_CMD_BMP_EN(cmd, MCHIP_FEATURE_PP_EN(lchip,CTC_FEATURE_SCL)), &tcam_entry);
        /* 0 is reasonable */
        if (p_wb_scl_igs_tcam_entry->acl_profile_valid && (!DRV_FROM_TMM(lchip)))
        {
            if (SYS_SCL_ACTION_INGRESS == temp_ad.com.action_type)
            {
                sal_memset(&acl, 0, sizeof(acl));
                acl.profile_id = (GetDsUserId(V, capwapUserSvlanId_f,  tempds_ad)>>8);
                cmd = DRV_IOR(DsSclAclControlProfile_t, DRV_ENTRY_FLAG);
                CTC_ERROR_RETURN(DRV_IOCTL(lchip, acl.profile_id, DRV_CMD_BMP_EN(cmd, MCHIP_FEATURE_PP_EN(lchip,CTC_FEATURE_SCL)), &acl.acl_control_profile));
                acl.is_scl = 1;
                CTC_ERROR_RETURN(ctc_spool_add(p_usw_scl_master[lchip]->acl_spool, &acl, NULL, &p_acl));
            }
            else
            {
                acl.profile_id = (GetDsTunnelId(V, aclControlProfileId_f, tempds_ad)>>8);

                cmd = DRV_IOR(DsTunnelAclControlProfile_t, DRV_ENTRY_FLAG);
                CTC_ERROR_RETURN(DRV_IOCTL(lchip, acl.profile_id, DRV_CMD_BMP_EN(cmd, MCHIP_FEATURE_PP_EN(lchip,CTC_FEATURE_SCL)), &acl.acl_control_profile));

                acl.is_scl = 0;

                CTC_ERROR_RETURN(ctc_spool_add(p_usw_scl_master[lchip]->acl_spool, &acl, NULL, &p_acl));
            }
            temp_ad.acl_profile = p_acl;
            temp_ad.acl_profile_id = acl.profile_id;
        }

        if(temp_ad.com.action_type == SYS_SCL_ACTION_INGRESS)
        {
            if(DRV_FROM_TMM(lchip))
            {
                temp_ds = SYS_SCL_TEMP_USERID(p_action_buffer, SYS_SCL_USERID_BMP_LOGIC_PORT);
                temp_ad.vpws_oam_en = (GetDsUserId(V, vplsOamEn_f, tempds_ad) && GetTempDsLogicPort(V, vsiIdValid_f, temp_ds)) ? 1 : 0;
            }
            else
            {
                temp_ad.vpws_oam_en =  (GetDsUserId(V, vplsOamEn_f, tempds_ad) && GetDsUserId(V, userVlanPtr_f, tempds_ad)) ? 1 : 0;
            }
        }
        else if(!DRV_FROM_TMM(lchip) && SYS_SCL_ACTION_TUNNEL == temp_ad.com.action_type)
        {
            temp_ad.rpf_check_en = GetDsTunnelId(V, rpfCheckEn_f, tempds_ad);
        }
        
        if (DRV_FROM_TMM(lchip))
        {
            sal_memcpy(action_buffer, tempds_ad, sizeof(ds_t ));
            MCHIP_SCL(lchip)->move_dsuserid_to_temp(lchip, p_action_buffer, temp_ad.com.userid_bmp);

            temp_vlan_xlate = SYS_SCL_TEMP_USERID(p_action_buffer, SYS_SCL_USERID_BMP_VLAN_XLATE);
            vlan_action_valid = GetTempDsVlanXlate(V, vlanActionProfileValid_f, temp_vlan_xlate);
            vlan_edit_profile_id = GetTempDsVlanXlate(V, vlanActionProfileId_f, temp_vlan_xlate);
        }
        else
        {
             vlan_edit_profile_id = GetDsUserId(V, vlanActionProfileId_f, tempds_ad);
             vlan_action_valid = GetDsUserId(V, vlanActionProfileValid_f, tempds_ad);
        }

        /*wb relaoding inner_rmac_index */
        if (DRV_FROM_TMM(lchip) && SYS_SCL_ACTION_INGRESS == temp_ad.com.action_type)
        {
            temp_ds = SYS_SCL_TEMP_USERID(p_action_buffer, SYS_SCL_USERID_BMP_FLOW);
            if(((DRV_IS_AT(lchip) && !GetDsUserId(V, xAdEn_f, tempds_ad)) || DRV_IS_TMM(lchip))
                && !GetTempDsFlow(V, flexOpValid_f, temp_ds))
            {
                /*used for setting scl action, also compatiable for srv6 function*/
                temp_ad.inner_rmac_index = (GetTempDsFlow(V, routerMacProfileId_f, temp_ds) | ((GetDsUserId(V, auxData_f, tempds_ad) & 0x7) << 6));
            }
        }
        else if(SYS_SCL_ACTION_TUNNEL == temp_ad.com.action_type)
        {
            if (GetDsTunnelId(V, trillBfdEchoEn_f, tempds_ad))
            {
                temp_ad.inner_rmac_index =  GetDsTunnelId(V, routerMacProfile_f, tempds_ad) | ((GetDsTunnelId(V, auxData_f, tempds_ad) & 0x7) << 6);
            }
            else
            {
                temp_ad.inner_rmac_index =  GetDsTunnelId(V, routerMacProfile_f, tempds_ad);
            }
        }
        if(temp_ad.inner_rmac_index)
        {
            sal_memset(&inner_rmac, 0, sizeof(inner_rmac));
            CTC_ERROR_RETURN(sys_usw_l3if_get_inner_router_mac(lchip, temp_ad.inner_rmac_index, &inner_rmac));
            rmac_index = temp_ad.inner_rmac_index;
            CTC_ERROR_RETURN(sys_usw_l3if_binding_inner_router_mac(lchip, &inner_rmac, &rmac_index));
        }

        if (vlan_action_valid && (SYS_SCL_ACTION_INGRESS == p_scl_tcam_entry->he.action_type))
        {
            cmd = DRV_IOR(DsVlanActionProfile_t, DRV_ENTRY_FLAG);
            CTC_ERROR_RETURN(DRV_IOCTL(lchip, vlan_edit_profile_id, DRV_CMD_BMP_EN(cmd, MCHIP_FEATURE_PP_EN(lchip,CTC_FEATURE_SCL)), &sp_vlan_edit.action_profile));
            sp_vlan_edit.profile_id = vlan_edit_profile_id;
            CTC_ERROR_RETURN(ctc_spool_add(p_usw_scl_master[lchip]->vlan_edit_spool, &sp_vlan_edit, NULL, &p_sp_vlan_edit));
            temp_ad.vlan_edit = p_sp_vlan_edit;
            temp_ad.vlan_profile_id = vlan_edit_profile_id;
        }
        else
        {
             temp_ad.vlan_profile_id = 0x3FF;
        }

        MALLOC_ZERO(MEM_SCL_MODULE, p_malloc_tcam_ad, size[temp_ad.com.ad_type]);
        if (!p_malloc_tcam_ad)
        {
            return  CTC_E_NO_MEMORY;
        }
        igs_hash_key = !(SCL_ENTRY_IS_TCAM(p_scl_tcam_entry->he.key_type) || p_scl_tcam_entry->he.resolve_conflict) && (SYS_SCL_ACTION_EGRESS != p_scl_tcam_entry->he.action_type);
        _sys_usw_scl_mapping_ad(p_malloc_tcam_ad, &temp_ad, 0, igs_hash_key, p_scl_tcam_entry->he.direction);

        p_scl_tcam_entry->he.u.ad = p_malloc_tcam_ad;

        MALLOC_ZERO(MEM_SCL_MODULE, pe_tcam, sizeof(sys_scl_sw_tcam_entry_t));
        if (NULL == pe_tcam)
        {
            SYS_SCL_DBG_OUT(CTC_DEBUG_LEVEL_ERROR, " No memory \n");
            return CTC_E_NO_MEMORY;
        }
        pe_tcam->fpae.entry_id = p_scl_tcam_entry->he.entry_id;
        pe_tcam->fpae.offset_a = p_scl_tcam_entry->he.key_index;
        pe_tcam->fpae.priority = SYS_SCL_WB_DATA(p_wb_scl_igs_tcam_entry->priority);
        SYS_SCL_ENCODE_XKEY_FPA_SIZE(p_scl_flex_key, p_wb_scl_igs_tcam_entry, fpa_size)
        pe_tcam->fpae.step = SYS_SCL_GET_STEP(p_usw_scl_master[lchip]->fpa_size[p_scl_tcam_entry->he.key_type]);
        pe_tcam->fpae.flag = 1;
        pe_tcam->entry = &p_scl_tcam_entry->he;
        pb = &p_usw_scl_master[lchip]->fpa_block[SCL_ENCODE_BLOCK_ID(p_scl_tcam_entry->he.direction, p_scl_tcam_entry->he.group_priority)];
        pb->fpab.entries[p_scl_tcam_entry->he.key_index] = &pe_tcam->fpae;


        p_scl_tcam_entry->range_bitmap  = (SYS_SCL_KEY_TCAM_IPV6 == p_scl_tcam_entry->he.key_type) ? GetDsScl0MacIpv6Key640(V, rangeBitmap_f, tempds_key):
                                          (SYS_SCL_KEY_TCAM_IPV6_SINGLE == p_scl_tcam_entry->he.key_type) ? GetDsScl0Ipv6Key320(V, rangeBitmap_f,tempds_key):
                                          (SYS_SCL_KEY_TCAM_IPV4 == p_scl_tcam_entry->he.key_type) ? GetDsScl0MacL3Key320(V, rangeBitmap_f, tempds_key) : 0;


        /* for inner entry need to restore entry-id-opf */
        if(SCL_INNER_ENTRY_ID(p_scl_tcam_entry->he.entry_id))
        {
            sys_scl_tcam_entry_key_t* tcam_entry;               /* when do hash insert, the data to inserted must be a pointer */
            uint8 loop = 0;
            tbl_entry_t          entry;
            uint32      hw_key_index  = 0;
            uint32      hw_ad_index   = 0;

            sys_usw_opf_t opf;
            sal_memset(&opf, 0, sizeof(sys_usw_opf_t));
            opf.pool_index = 0;
            opf.pool_type  = p_usw_scl_master[pp_base]->opf_type_entry_id;

            sys_usw_opf_alloc_offset_from_position(pp_base, &opf, 1, (p_scl_tcam_entry->he.entry_id - SYS_SCL_MIN_INNER_ENTRY_ID));


            MALLOC_ZERO(MEM_SCL_MODULE, tcam_entry, sizeof(sys_scl_tcam_entry_key_t));
            if (NULL == tcam_entry)
            {
                SYS_SCL_DBG_OUT(CTC_DEBUG_LEVEL_ERROR, " No memory \n");
                return CTC_E_NO_MEMORY;
            }
            entry.data_entry = tcam_entry->key;
            entry.mask_entry = tcam_entry->mask;
            cmd = DRV_IOR(key_id, DRV_ENTRY_FLAG);
            _sys_usw_scl_get_index(lchip, key_id, &p_scl_tcam_entry->he, &hw_key_index, &hw_ad_index);
            DRV_IOCTL(lchip, hw_key_index, DRV_CMD_BMP_EN(cmd, MCHIP_FEATURE_PP_EN(lchip,CTC_FEATURE_SCL)), &entry);

            for(loop = 0; loop < SYS_SCL_MAX_KEY_SIZE_IN_WORD; loop++)
            {
                tcam_entry->key[loop] = tcam_entry->key[loop] & tcam_entry->mask[loop];
            }
            tcam_entry->scl_id = p_scl_tcam_entry->he.group_priority;
            tcam_entry->p_entry = &p_scl_tcam_entry->he;

            /* add to hash by key */
            if (NULL == ctc_hash_insert(p_usw_scl_master[lchip]->tcam_entry_by_key, tcam_entry))
            {
                mem_free(tcam_entry);
                SYS_SCL_DBG_OUT(CTC_DEBUG_LEVEL_ERROR, " [SCL] Hash insert fail\n");
                return CTC_E_NO_MEMORY;
            }

        }
        if(DRV_FROM_AT(lchip) && MCHIP_FEATURE_PP_EN(lchip, CTC_FEATURE_SCL))
        {
            CTC_BIT_SET(pp_bmp,(lchip - SYS_PP_BASE(lchip)));
            if( (SYS_SCL_IS_ENTRY_HASH_BITMAP(p_scl_tcam_entry->he.entry_id,p_wb_scl_igs_tcam_entry->group_id)) ||
                p_scl_tcam_entry->he.entry_id <= CTC_SCL_MAX_USER_ENTRY_ID)
            {
                sys_usw_scl_add_entry_hash_inner(SYS_PP_BASE(lchip), p_scl_tcam_entry->he.entry_id,pp_bmp);
            }
        }

        /* add to group entry list's head */
        ctc_list_pointer_insert_head(&(pg->entry_list), &(p_scl_tcam_entry->he.head));

        if (temp_ad.bind_nh)
        {
            _sys_usw_scl_bind_nexthop(lchip, &p_scl_tcam_entry->he, temp_ad.nexthop_id);
        }
    }
    return CTC_E_NONE;
}

int32
_sys_usw_scl_wb_sync_igs_tcam_entry_func(void* bucket_data, void* user_data)
{
    uint32 max_entry_num = 0;
    sys_scl_sw_entry_t* p_scl_entry    = NULL;
    sys_wb_scl_igs_tcam_entry_t*   p_wb_scl_igs_tcam_entry = NULL;
    ctc_wb_data_t*           p_wb_data      = NULL;
    sys_scl_flexed_key_t* p_scl_flex_key = NULL;
    sys_scl_sw_block_t*      p_block = NULL;
    uint8                    lchip = 0;
    uint8                    is_default,is_tcam_key;

    p_scl_entry = (sys_scl_sw_entry_t*)bucket_data;
    p_wb_data   = (ctc_wb_data_t*)(((sys_scl_traverse_data_t*)user_data)->data0);
    p_block   = (sys_scl_sw_block_t*)(((sys_scl_traverse_data_t*)user_data)->data1);
    lchip     = ((sys_scl_traverse_data_t*)user_data)->value0;
    is_default = ((sys_scl_traverse_data_t*)user_data)->value1;

    p_wb_scl_igs_tcam_entry = (sys_wb_scl_igs_tcam_entry_t*)p_wb_data->buffer + p_wb_data->valid_cnt;
    sal_memset(p_wb_scl_igs_tcam_entry, 0, sizeof(sys_wb_scl_igs_tcam_entry_t));

    max_entry_num = p_wb_data->buffer_len / sizeof(sys_wb_scl_igs_tcam_entry_t);

    is_tcam_key = SCL_ENTRY_IS_TCAM(p_scl_entry->key_type);

    if(!is_tcam_key)
    {
        return CTC_E_NONE;
    }

    if (p_scl_entry->is_buffer)
    {
         /* uninstall entry not sync, but need to update fpa count for tcam entry
          * need to clear valid bit after restore,so need to store key index for hash entry
          */
        if (!is_default && (SCL_ENTRY_IS_TCAM(p_scl_entry->key_type) || (p_scl_entry->resolve_conflict)))
        {
            uint8 fpa_size =0;
            p_scl_flex_key = (sys_scl_flexed_key_t*)p_scl_entry->u.temp_entry->fk;
            SYS_SCL_ENCODE_XKEY_FPA_SIZE(p_scl_flex_key, p_scl_entry, fpa_size)
            if (p_scl_flex_key && p_scl_flex_key->is_xkey && !p_scl_flex_key->is_replace)
            {
                fpa_size = fpa_size+1;
            }

            (p_block[SCL_ENCODE_BLOCK_ID(p_scl_entry->direction, p_scl_entry->group_priority)].fpab.free_count) += (SYS_SCL_GET_STEP(fpa_size));
            (p_block[SCL_ENCODE_BLOCK_ID(p_scl_entry->direction, p_scl_entry->group_priority)].fpab.sub_free_count[fpa_size])++;

            return CTC_E_NONE;
        }
        else if(is_default || p_scl_entry->hash_valid == 0)
        {
            return CTC_E_NONE;
        }
    }

    CTC_ERROR_RETURN(_sys_usw_scl_wb_mapping_igs_tcam_entry(lchip, p_wb_scl_igs_tcam_entry, (sys_scl_sw_entry_tcam_t*)p_scl_entry, 1, is_default));

    if (++p_wb_data->valid_cnt == max_entry_num)
    {
        CTC_ERROR_RETURN(ctc_wb_add_entry(p_wb_data));
        p_wb_data->valid_cnt = 0;
    }
     return CTC_E_NONE;
}
int32
_sys_usw_scl_wb_mapping_igs_hash_entry(uint8 lchip, sys_wb_scl_igs_hash_entry_t* p_wb_scl_igs_hash_entry, sys_scl_sw_entry_t* p_scl_entry, uint8 is_sync, uint8 is_default)
{
    uint32 cmd;
    uint8  hash_uninstall = 0;
    sys_scl_flexed_key_t* p_scl_flex_key = NULL;
    sys_scl_sw_igs_ad_t temp_ad;
    sys_scl_sw_block_t*         pb = NULL;

    sal_memset(&temp_ad, 0, sizeof(sys_scl_sw_igs_ad_t));
    if (is_sync)
    {
        _sys_usw_scl_mapping_ad(p_scl_entry->u.ad, &temp_ad, 1, 0, p_scl_entry->direction);
        p_wb_scl_igs_hash_entry->entry_id             = p_scl_entry->entry_id;
        p_wb_scl_igs_hash_entry->key_type             = p_scl_entry->key_type;
        p_wb_scl_igs_hash_entry->resolve_conflict     = p_scl_entry->resolve_conflict;
        p_wb_scl_igs_hash_entry->uninstall            = p_scl_entry->uninstall;
        p_wb_scl_igs_hash_entry->is_xkey              = p_scl_entry->is_xkey;
        p_wb_scl_igs_hash_entry->is_half              = p_scl_entry->is_half;
        p_wb_scl_igs_hash_entry->group_id             = is_default ? 0 : p_scl_entry->group_id;
        p_wb_scl_igs_hash_entry->hash_valid           =  p_scl_entry->hash_valid;
        p_wb_scl_igs_hash_entry->vrange_gid           =  p_scl_entry->vrange_gid;
        p_wb_scl_igs_hash_entry->u1_type              = temp_ad.com.u1_type;
        p_wb_scl_igs_hash_entry->u2_type              = temp_ad.com.u2_type;
        p_wb_scl_igs_hash_entry->u3_type              = temp_ad.com.u3_type;
        p_wb_scl_igs_hash_entry->u4_type              = temp_ad.com.u4_type;
        p_wb_scl_igs_hash_entry->u5_type              = temp_ad.com.u5_type;
        p_wb_scl_igs_hash_entry->is_service_policer   = temp_ad.is_service_policer;
        p_wb_scl_igs_hash_entry->bind_nh              = temp_ad.bind_nh;

        
        p_wb_scl_igs_hash_entry->acl_profile_valid = 0;
        if(temp_ad.acl_profile)
        {
            p_wb_scl_igs_hash_entry->acl_profile_valid = 1;
        }
        p_wb_scl_igs_hash_entry->fwd_bmp             = temp_ad.com.fwd_bmp;
        p_wb_scl_igs_hash_entry->is_scl              = temp_ad.acl_profile ? temp_ad.acl_profile->is_scl : 0;
        p_wb_scl_igs_hash_entry->l3_type              = p_scl_entry->l3_type;
        p_wb_scl_igs_hash_entry->l4_type              = p_scl_entry->l4_type;
        p_wb_scl_igs_hash_entry->action_type          = p_scl_entry->action_type;
        p_wb_scl_igs_hash_entry->fwd_type             = temp_ad.fwd_type;
        p_wb_scl_igs_hash_entry->ad_type              = temp_ad.com.ad_type;
        p_wb_scl_igs_hash_entry->userid_bmp          = temp_ad.com.userid_bmp;
        p_wb_scl_igs_hash_entry->hash_field_sel_id   = p_scl_entry->hash_field_sel_id;
        p_wb_scl_igs_hash_entry->nexthop_id           = temp_ad.nexthop_id;
        SYS_SCL_COPY_DB_TO_WB(p_wb_scl_igs_hash_entry->key_index, p_scl_entry->key_index);
        p_wb_scl_igs_hash_entry->key_bmp              = p_scl_entry->key_bmp;
        p_wb_scl_igs_hash_entry->service_id           = temp_ad.service_id;
        p_wb_scl_igs_hash_entry->priority = 0;
        if (!is_default && p_scl_entry->resolve_conflict)
        {
            pb = &p_usw_scl_master[lchip]->fpa_block[SCL_ENCODE_BLOCK_ID(p_scl_entry->direction, p_scl_entry->group_priority)];
            SYS_SCL_COPY_DB_TO_WB(p_wb_scl_igs_hash_entry->priority, pb->fpab.entries[p_scl_entry->key_index]->priority);
        }
        sal_memcpy(p_wb_scl_igs_hash_entry->action_bmp, p_scl_entry->action_bmp, sizeof(p_scl_entry->action_bmp));
    }
    else
    {
        sys_scl_sw_group_t* pg = NULL;
        sys_scl_action_acl_t acl;
        sys_scl_action_acl_t* p_acl = NULL;
        void *temp_vlan_xlate = NULL;
        void *temp_logic_port = NULL;
        uint32* temp_ds = NULL;
        sys_scl_sp_vlan_edit_t* p_sp_vlan_edit = NULL;
        void* p_malloc_ad = NULL;
        sys_scl_sp_vlan_edit_t sp_vlan_edit;
        ds_t action_buffer = {0};
        void* p_action_buffer = action_buffer;
        uint32 key_id = 0;
        uint32 act_id = 0;
        uint32 ad_index  = 0;
        uint32 hw_key_index  = 0;
        uint32  hw_ad_index   = 0;
        uint32 entry_size = 0;
        ds_t tempds_ad;
        ds_t tempds_mask;
        ds_t ad;
        uint8 vlan_edit_profile_id = 0;
        uint8 vlan_action_valid;
        uint8  count_size = 0;
        uint8 igs_hash_key = 0;
        uint8 fpa_size = 0;
        uint16 def_entry_index = 0;
        uint8 scl_id = 0;
        uint8 drv_key_type = 0;
        uint16 lport = 0;
        uint16 pp_bmp = 0;
        uint8 pp_base =  sys_usw_vchip_get_pp_base(lchip);
        mac_addr_t inner_rmac;
        uint16 rmac_index = 0;
        uint8 size[SYS_SCL_SW_AD_TYPE_MAX] = {CTC_OFFSET_OF(sys_scl_sw_igs_ad0_t, calc_key_len),
                                                 CTC_OFFSET_OF(sys_scl_sw_igs_ad1_t, calc_key_len),
                                                 CTC_OFFSET_OF(sys_scl_sw_igs_ad2_t, calc_key_len),
                                                 CTC_OFFSET_OF(sys_scl_sw_igs_ad3_t, calc_key_len),
                                                 CTC_OFFSET_OF(sys_scl_sw_igs_ad_t, calc_key_len),
                                                 sizeof(sys_scl_sw_egs_ad_t)};
        uint8 dft_size[SYS_SCL_SW_AD_TYPE_IGS_MAX] = {sizeof(sys_scl_sw_igs_ad0_t),
                                               sizeof(sys_scl_sw_igs_ad1_t),
                                               sizeof(sys_scl_sw_igs_ad2_t),
                                               sizeof(sys_scl_sw_igs_ad3_t),
                                               sizeof(sys_scl_sw_igs_ad_t)};
        sal_memset(&tempds_ad, 0, sizeof(ds_t));
        sal_memset(&tempds_mask, 0, sizeof(ds_t));

        p_scl_entry->entry_id               = p_wb_scl_igs_hash_entry->entry_id;
        p_scl_entry->key_type               = p_wb_scl_igs_hash_entry->key_type;
        p_scl_entry->resolve_conflict       = p_wb_scl_igs_hash_entry->resolve_conflict;
        p_scl_entry->uninstall              = p_wb_scl_igs_hash_entry->uninstall;
        p_scl_entry->vrange_gid             = p_wb_scl_igs_hash_entry->vrange_gid;
        p_scl_entry->hash_valid             = p_wb_scl_igs_hash_entry->hash_valid;
        p_scl_entry->action_type            = p_wb_scl_igs_hash_entry->action_type;
        p_scl_entry->is_half                = p_wb_scl_igs_hash_entry->is_half;
        p_scl_entry->is_xkey                = p_wb_scl_igs_hash_entry->is_xkey;
        p_scl_entry->group_id               = p_wb_scl_igs_hash_entry->group_id;
        p_scl_entry->direction              = CTC_INGRESS;
        p_scl_entry->is_default             = is_default;
        temp_ad.com.u1_type                 = p_wb_scl_igs_hash_entry->u1_type;
        temp_ad.com.u2_type                 = p_wb_scl_igs_hash_entry->u2_type;
        temp_ad.com.u3_type                 = p_wb_scl_igs_hash_entry->u3_type;
        temp_ad.com.u4_type                 = p_wb_scl_igs_hash_entry->u4_type;
        temp_ad.com.u5_type                 = p_wb_scl_igs_hash_entry->u5_type;
        temp_ad.is_service_policer          = p_wb_scl_igs_hash_entry->is_service_policer;
        temp_ad.bind_nh                     = p_wb_scl_igs_hash_entry->bind_nh;
        temp_ad.com.action_type             = p_wb_scl_igs_hash_entry->action_type;
        temp_ad.com.userid_bmp              = p_wb_scl_igs_hash_entry->userid_bmp;
        temp_ad.com.fwd_bmp                 = p_wb_scl_igs_hash_entry->fwd_bmp;
        temp_ad.com.ad_type                 = p_wb_scl_igs_hash_entry->ad_type;
        temp_ad.nexthop_id                  = p_wb_scl_igs_hash_entry->nexthop_id;
        temp_ad.fwd_type                    = p_wb_scl_igs_hash_entry->fwd_type;
        temp_ad.com.lchip                   = lchip;
        temp_ad.acl_profile_id              = 0xFF;
        p_scl_entry->l3_type                = p_wb_scl_igs_hash_entry->l3_type;
        p_scl_entry->l4_type                = p_wb_scl_igs_hash_entry->l4_type;
        p_scl_entry->hash_field_sel_id      = p_wb_scl_igs_hash_entry->hash_field_sel_id;
        p_scl_entry->key_index              = SYS_SCL_WB_DATA(p_wb_scl_igs_hash_entry->key_index);
        p_scl_entry->key_bmp                = p_wb_scl_igs_hash_entry->key_bmp;
        temp_ad.service_id                  = p_wb_scl_igs_hash_entry->service_id;
        
        sal_memcpy(p_scl_entry->action_bmp, p_wb_scl_igs_hash_entry->action_bmp, sizeof(p_scl_entry->action_bmp));
       
        if(!is_default)
        {
            _sys_usw_scl_get_group_by_gid(lchip, p_wb_scl_igs_hash_entry->group_id, &pg);
            p_scl_entry->group_priority =  pg->priority;
            _sys_usw_scl_get_table_id(lchip, pg->priority, p_scl_entry, &key_id, &act_id);
            if (p_scl_entry->resolve_conflict)
            {
                _sys_usw_scl_get_index(lchip, key_id, p_scl_entry, &hw_key_index, &hw_ad_index);
                temp_ad.com.ad_index = hw_ad_index;
                cmd = DRV_IOR(act_id , DRV_ENTRY_FLAG);
                DRV_IOCTL(lchip, hw_ad_index , DRV_CMD_BMP_EN(cmd, MCHIP_FEATURE_PP_EN(lchip,CTC_FEATURE_SCL)), &tempds_ad);
            }
            else
            {
                drv_acc_in_t in;
                drv_acc_out_t out;
                sal_memset(&in, 0, sizeof(in));
                sal_memset(&out, 0, sizeof(out));
                in.type = DRV_ACC_TYPE_LOOKUP;
                in.op_type = DRV_ACC_OP_BY_INDEX;
                in.tbl_id = key_id;
                drv_acc_get_hash_module(lchip,in.tbl_id, &in.module);
                in.index = p_scl_entry->key_index;
                in.level = p_scl_entry->group_priority;
                in.oper_bmp = DRV_ACC_BMP_EN(MCHIP_FEATURE_PP_EN(lchip, CTC_FEATURE_SCL));
                CTC_ERROR_RETURN(drv_acc_api(lchip, &in, &out));

                ad_index =  GetDsUserIdPortHashKey(V, dsAdIndex_f, out.data);
                cmd = DRV_IOR(act_id , DRV_ENTRY_FLAG);
                DRV_IOCTL(lchip,ad_index, DRV_CMD_BMP_EN(cmd, MCHIP_FEATURE_PP_EN(lchip,CTC_FEATURE_SCL)), &tempds_ad);
                temp_ad.com.ad_index = ad_index;
            }
        }
        else
        {
            scl_id =(p_scl_entry->entry_id>>24);
            lport = ((p_scl_entry->entry_id>>8)&0xFFFF);

            if (SYS_SCL_ACTION_TUNNEL ==temp_ad.com.action_type)
            {
                _sys_usw_scl_map_drv_tunnel_type(lchip, p_scl_entry->key_type, &drv_key_type);
            }

            if (SYS_SCL_ACTION_INGRESS == temp_ad.com.action_type)
            {
                act_id = (0 == scl_id? DsUserId_t : DsUserId1_t);
                def_entry_index = p_usw_scl_master[lchip]->igs_default_base[scl_id] + 2 * lport;
            }
            else if(SYS_SCL_ACTION_EGRESS == temp_ad.com.action_type)
            {
                act_id = DRV_FROM_AT(lchip) ? (0 == scl_id ? DsVlanXlateDefault0_t : DsVlanXlateDefault1_t) : DsVlanXlateDefault_t;
                def_entry_index= lport;
            }
            else
            {
                act_id = (0 == scl_id? DsTunnelId_t: DsTunnelId1_t);
                def_entry_index = p_usw_scl_master[lchip]->tunnel_default_base[scl_id] + 2 * drv_key_type;
            }
            temp_ad.com.ad_index = def_entry_index;
            cmd = DRV_IOR(act_id , DRV_ENTRY_FLAG);
            DRV_IOCTL(lchip,def_entry_index, DRV_CMD_BMP_EN(cmd, MCHIP_FEATURE_PP_EN(lchip,CTC_FEATURE_SCL)), &tempds_ad);
        }

        /*Only hash uninstalled entry need to clear valid bit*/
        hash_uninstall = p_scl_entry->uninstall && !is_default;
        if(hash_uninstall && p_scl_entry->hash_valid)
        {
            int32 ret = 0;
            drv_acc_in_t in;
            drv_acc_out_t out;
            uint32 pu32[MAX_ENTRY_WORD] = { 0 };

            sal_memset(&in, 0, sizeof(in));
            sal_memset(&out, 0, sizeof(out));

            drv_set_warmboot_status(lchip, DRV_WB_STATUS_DONE);
            in.type = DRV_ACC_TYPE_ADD;
            in.op_type = DRV_ACC_OP_BY_INDEX;
            in.tbl_id = key_id;
            drv_acc_get_hash_module(lchip,in.tbl_id, &in.module);
            in.data   = &pu32;
            in.index  = p_scl_entry->key_index;
            in.oper_bmp = DRV_ACC_BMP_EN(MCHIP_FEATURE_PP_EN(lchip, CTC_FEATURE_SCL));
            ret = drv_acc_api(lchip, &in, &out);
            drv_set_warmboot_status(lchip, DRV_WB_STATUS_RELOADING);
            return ret;
        }

        CTC_ERROR_RETURN(_sys_usw_scl_get_flex_key_node(lchip, p_scl_entry, &p_scl_flex_key));
        if(p_scl_flex_key)
        {
            p_scl_flex_key->entry_count++;
        }
        
        if (DRV_FROM_TMM(lchip))
        {
            sal_memcpy(action_buffer, tempds_ad, sizeof(ds_t));
            MCHIP_SCL(lchip)->move_dsuserid_to_temp(lchip, p_action_buffer, temp_ad.com.userid_bmp);

            temp_vlan_xlate = SYS_SCL_TEMP_USERID(p_action_buffer, SYS_SCL_USERID_BMP_VLAN_XLATE);
            vlan_action_valid = GetTempDsVlanXlate(V, vlanActionProfileValid_f, temp_vlan_xlate);
            vlan_edit_profile_id = GetTempDsVlanXlate(V, vlanActionProfileId_f, temp_vlan_xlate);
        }
        else
        {
            vlan_edit_profile_id = GetDsUserId(V, vlanActionProfileId_f, tempds_ad);
            vlan_action_valid = GetDsUserId(V, vlanActionProfileValid_f, tempds_ad);
        }
                        
        if (vlan_action_valid && (SYS_SCL_ACTION_INGRESS == p_scl_entry->action_type))
        {
           cmd = DRV_IOR(DsVlanActionProfile_t, DRV_ENTRY_FLAG);
           CTC_ERROR_RETURN(DRV_IOCTL(lchip, vlan_edit_profile_id, DRV_CMD_BMP_EN(cmd, MCHIP_FEATURE_PP_EN(lchip,CTC_FEATURE_SCL)), &sp_vlan_edit.action_profile));
           sp_vlan_edit.profile_id = vlan_edit_profile_id;
           CTC_ERROR_RETURN(ctc_spool_add(p_usw_scl_master[lchip]->vlan_edit_spool, &sp_vlan_edit, NULL, &p_sp_vlan_edit));
           temp_ad.vlan_edit = p_sp_vlan_edit;
           temp_ad.vlan_profile_id = vlan_edit_profile_id;
        }
        else
        {
            temp_ad.vlan_profile_id = 0x3FF;
        }
        
        /*wb relaoding inner_rmac_index */
        if (DRV_FROM_TMM(lchip) && SYS_SCL_ACTION_INGRESS == p_scl_entry->action_type)
        {
            temp_ds = SYS_SCL_TEMP_USERID(p_action_buffer, SYS_SCL_USERID_BMP_FLOW);
            if(((DRV_IS_AT(lchip) && !GetDsUserId(V, xAdEn_f, tempds_ad)) || DRV_IS_TMM(lchip))
                && !GetTempDsFlow(V, flexOpValid_f, temp_ds))
            {
                /*used for setting scl action, also compatiable for srv6 function*/
                temp_ad.inner_rmac_index = (GetTempDsFlow(V, routerMacProfileId_f, temp_ds) | ((GetDsUserId(V, auxData_f, tempds_ad) & 0x7) << 6));
            }
        }
        else if(SYS_SCL_ACTION_TUNNEL == p_scl_entry->action_type)
        {
            if (DRV_FROM_AT(lchip) && GetDsTunnelId(V, trillBfdEchoEn_f, tempds_ad))
            {
                temp_ad.inner_rmac_index =  GetDsTunnelId(V, routerMacProfile_f, tempds_ad) | ((GetDsTunnelId(V, auxData_f, tempds_ad) & 0x7) << 6);
            }
            else
            {
                temp_ad.inner_rmac_index =  GetDsTunnelId(V, routerMacProfile_f, tempds_ad);
            }
        }
        if(temp_ad.inner_rmac_index)
        {
            sal_memset(&inner_rmac, 0, sizeof(inner_rmac));
            CTC_ERROR_RETURN(sys_usw_l3if_get_inner_router_mac(lchip, temp_ad.inner_rmac_index, &inner_rmac));
            rmac_index = temp_ad.inner_rmac_index;
            CTC_ERROR_RETURN(sys_usw_l3if_binding_inner_router_mac(lchip, &inner_rmac, &rmac_index));
        }

        CTC_ERROR_RETURN(sys_usw_ftm_query_table_entry_size(lchip, key_id, &entry_size));
        count_size = entry_size / SCL_KEY_USW_SIZE_80;
        count_size =    !p_scl_entry->resolve_conflict ? count_size :
                        p_scl_entry->direction == CTC_INGRESS ? count_size : (count_size*2);
        if (!is_default && ((!SCL_ENTRY_IS_TCAM(p_scl_entry->key_type) && !p_scl_entry->resolve_conflict) || (p_scl_entry->resolve_conflict && DRV_FROM_TMM(lchip))))
        {
            p_usw_scl_master[lchip]->entry_count[p_scl_entry->group_priority][p_scl_entry->action_type] += count_size;
        }
        /* restore hash field select count */
        if (((SYS_SCL_KEY_HASH_L2 == p_scl_entry->key_type) || (SYS_SCL_KEY_HASH_L2_UDF == p_scl_entry->key_type) || (SYS_SCL_KEY_HASH_L3_UDF == p_scl_entry->key_type)) && !is_default)
        {
            p_usw_scl_master[pp_base]->hash_sel_profile_count[p_scl_entry->hash_field_sel_id] += 1;
        }

        /* 0 is reasonable */
        if (p_wb_scl_igs_hash_entry->acl_profile_valid && (!DRV_FROM_TMM(lchip)))
        {
            sal_memset(&acl, 0, sizeof(acl));
            if (p_wb_scl_igs_hash_entry->is_scl)
            {
                acl.profile_id = (GetDsUserId(V, capwapUserSvlanId_f, tempds_ad)>>8);
                cmd = DRV_IOR(DsSclAclControlProfile_t, DRV_ENTRY_FLAG);
                CTC_ERROR_RETURN(DRV_IOCTL(lchip, acl.profile_id, DRV_CMD_BMP_EN(cmd, MCHIP_FEATURE_PP_EN(lchip,CTC_FEATURE_SCL)), &acl.acl_control_profile));
                acl.is_scl = 1;
                CTC_ERROR_RETURN(ctc_spool_add(p_usw_scl_master[lchip]->acl_spool, &acl, NULL, &p_acl));
            }
            else
            {
                acl.profile_id = GetDsTunnelId(V, aclControlProfileId_f, tempds_ad);

                cmd = DRV_IOR(DsTunnelAclControlProfile_t, DRV_ENTRY_FLAG);
                CTC_ERROR_RETURN(DRV_IOCTL(lchip, acl.profile_id, DRV_CMD_BMP_EN(cmd, MCHIP_FEATURE_PP_EN(lchip,CTC_FEATURE_SCL)), &acl.acl_control_profile));

                acl.is_scl = 0;

                CTC_ERROR_RETURN(ctc_spool_add(p_usw_scl_master[lchip]->acl_spool, &acl, NULL, &p_acl));
            }
            temp_ad.acl_profile = p_acl;
            temp_ad.acl_profile_id = acl.profile_id;
        }

        if(p_scl_entry->action_type == SYS_SCL_ACTION_INGRESS)
        {
            if(DRV_FROM_TMM(lchip))
            {
                temp_logic_port = SYS_SCL_TEMP_USERID(p_action_buffer, SYS_SCL_USERID_BMP_LOGIC_PORT);
                temp_ad.vpws_oam_en = (GetDsUserId(V, vplsOamEn_f, tempds_ad) && GetTempDsLogicPort(V, vsiIdValid_f, temp_logic_port)) ? 1 : 0;
            }
            else
            {
                temp_ad.vpws_oam_en =  (GetDsUserId(V, vplsOamEn_f, tempds_ad) && GetDsUserId(V, userVlanPtr_f, tempds_ad)) ? 1 : 0;
            }
        }
        else if(SYS_SCL_ACTION_TUNNEL == p_scl_entry->action_type)
        {
            if(!DRV_FROM_TMM(lchip))
            {
                temp_ad.rpf_check_en = GetDsTunnelId(V, rpfCheckEn_f, tempds_ad);
            }
        }

        if(is_default || p_scl_entry->resolve_conflict)
        {
            MALLOC_ZERO(MEM_SCL_MODULE, p_malloc_ad,is_default? dft_size[temp_ad.com.ad_type] : size[temp_ad.com.ad_type]);
            if (!p_malloc_ad)
            {
                return  CTC_E_NO_MEMORY;
            }
            igs_hash_key = !(SCL_ENTRY_IS_TCAM(p_scl_entry->key_type) || p_scl_entry->resolve_conflict) && (SYS_SCL_ACTION_EGRESS != p_scl_entry->action_type);
            _sys_usw_scl_mapping_ad(p_malloc_ad, &temp_ad, 0, igs_hash_key, p_scl_entry->direction);
            p_scl_entry->u.ad = p_malloc_ad;
        }

        if(is_default || (hash_uninstall && p_scl_entry->key_index == 0xFFFF))
        {
          return CTC_E_NONE;
        }

        /* for inner hash entry */
        if (!SCL_ENTRY_IS_TCAM(p_scl_entry->key_type) && !p_scl_entry->resolve_conflict)
        {
            sys_scl_hash_key_entry_t* hash_entry;               /* when do hash insert, the data to inserted must be a pointer */
            if (SYS_SCL_ACTION_EGRESS != p_scl_entry->action_type)
            {
                temp_ad.com.action_type = p_scl_entry->action_type;
                temp_ad.com.is_half = p_scl_entry->is_half;
                temp_ad.com.priority = (1 == p_usw_scl_master[lchip]->hash_mode ? pg->priority : 0);

                CTC_MAX_VALUE_CHECK(temp_ad.com.priority, 1);
                igs_hash_key = !(SCL_ENTRY_IS_TCAM(p_scl_entry->key_type) || p_scl_entry->resolve_conflict) && (SYS_SCL_ACTION_EGRESS != p_scl_entry->action_type);

                _sys_usw_scl_mapping_ad(&ad, &temp_ad, 0, igs_hash_key, p_scl_entry->direction);
                CTC_ERROR_RETURN(ctc_spool_add(p_usw_scl_master[lchip]->ad_spool[temp_ad.com.priority*SYS_SCL_SW_AD_TYPE_IGS_MAX+temp_ad.com.ad_type], &ad, NULL, &p_scl_entry->u.ad));
            }
            if(SYS_SCL_IS_INNER_ENTRY(p_scl_entry->entry_id))
            {
                MALLOC_ZERO(MEM_SCL_MODULE, hash_entry, sizeof(sys_scl_hash_key_entry_t));
                if (NULL == hash_entry)
                {
                    SYS_SCL_DBG_OUT(CTC_DEBUG_LEVEL_ERROR, " No memory \n");
                    return CTC_E_NO_MEMORY;
                }
                hash_entry->action_type = p_scl_entry->action_type;
                hash_entry->entry_id = p_scl_entry->entry_id;

                hash_entry->scl_id = pg->priority;
                hash_entry->key_index = p_scl_entry->key_index;

                /* add to hash by key */
                if (NULL == ctc_hash_insert(p_usw_scl_master[lchip]->hash_key_entry, hash_entry))
                {
                    SYS_SCL_DBG_OUT(CTC_DEBUG_LEVEL_ERROR, " [SCL] Hash insert fail\n");
                    mem_free(hash_entry);
                    return CTC_E_NO_MEMORY;
                }
            }

        }
        else if(p_scl_entry->resolve_conflict)
        {
            sys_scl_sw_tcam_entry_t* pe_tcam = NULL;
            MALLOC_ZERO(MEM_SCL_MODULE, pe_tcam, sizeof(sys_scl_sw_tcam_entry_t));
            if (NULL == pe_tcam)
            {
                SYS_SCL_DBG_OUT(CTC_DEBUG_LEVEL_ERROR, " No memory \n");
                return CTC_E_NO_MEMORY;

            }
            pe_tcam->fpae.entry_id = p_scl_entry->entry_id;
            pe_tcam->fpae.offset_a = p_scl_entry->key_index;
            pe_tcam->fpae.priority =  SYS_SCL_WB_DATA(p_wb_scl_igs_hash_entry->priority);
            SYS_SCL_ENCODE_XKEY_FPA_SIZE(p_scl_flex_key, p_scl_entry, fpa_size)
            pe_tcam->fpae.step = SYS_SCL_GET_STEP(p_usw_scl_master[lchip]->fpa_size[p_scl_entry->key_type]);
            pe_tcam->fpae.flag = !(p_scl_entry->uninstall);
            pe_tcam->entry = p_scl_entry;
            pb = &p_usw_scl_master[lchip]->fpa_block[SCL_ENCODE_BLOCK_ID(p_scl_entry->direction, pg->priority)];
            pb->fpab.entries[p_scl_entry->key_index] = &pe_tcam->fpae;
        }

        /* for inner entry need to restore entry-id-opf */
        if(SCL_INNER_ENTRY_ID(p_scl_entry->entry_id))
        {
            sys_usw_opf_t opf;
            sal_memset(&opf, 0, sizeof(sys_usw_opf_t));
            opf.pool_index = 0;
            opf.pool_type  = p_usw_scl_master[pp_base]->opf_type_entry_id;

            sys_usw_opf_alloc_offset_from_position(pp_base, &opf, 1, (p_scl_entry->entry_id - SYS_SCL_MIN_INNER_ENTRY_ID));
            if (SCL_ENTRY_IS_TCAM(p_scl_entry->key_type) || p_scl_entry->resolve_conflict)
            {
                sys_scl_tcam_entry_key_t* tcam_entry;               /* when do hash insert, the data to inserted must be a pointer */
                uint8 loop = 0;
                tbl_entry_t          entry;
                uint32      hw_key_index  = 0;
                uint32      hw_ad_index   = 0;

                MALLOC_ZERO(MEM_SCL_MODULE, tcam_entry, sizeof(sys_scl_tcam_entry_key_t));
                if (NULL == tcam_entry)
                {
                    SYS_SCL_DBG_OUT(CTC_DEBUG_LEVEL_ERROR, " No memory \n");
                    return CTC_E_NO_MEMORY;
                }
                entry.data_entry = tcam_entry->key;
                entry.mask_entry = tcam_entry->mask;
                cmd = DRV_IOR(key_id, DRV_ENTRY_FLAG);
                _sys_usw_scl_get_index(lchip, key_id, p_scl_entry, &hw_key_index, &hw_ad_index);
                DRV_IOCTL(lchip, hw_key_index, DRV_CMD_BMP_EN(cmd, MCHIP_FEATURE_PP_EN(lchip,CTC_FEATURE_SCL)), &entry);

                for(loop = 0; loop < SYS_SCL_MAX_KEY_SIZE_IN_WORD; loop++)
                {
                    tcam_entry->key[loop] = tcam_entry->key[loop] & tcam_entry->mask[loop];
                }
                tcam_entry->scl_id = pg->priority;
                tcam_entry->p_entry = p_scl_entry;

                /* add to hash by key */
                if (NULL == ctc_hash_insert(p_usw_scl_master[lchip]->tcam_entry_by_key, tcam_entry))
                {
                    mem_free(tcam_entry);
                    SYS_SCL_DBG_OUT(CTC_DEBUG_LEVEL_ERROR, " [SCL] Hash insert fail\n");
                    return CTC_E_NO_MEMORY;
                }
            }
        }

        if(DRV_FROM_AT(lchip) && MCHIP_FEATURE_PP_EN(lchip, CTC_FEATURE_SCL))
        {
            CTC_BIT_SET(pp_bmp,(lchip - SYS_PP_BASE(lchip)));
            if((SYS_SCL_IS_ENTRY_HASH_BITMAP(p_scl_entry->entry_id,p_wb_scl_igs_hash_entry->group_id)) ||
                p_scl_entry->entry_id <= CTC_SCL_MAX_USER_ENTRY_ID)
            {
                sys_usw_scl_add_entry_hash_inner(SYS_PP_BASE(lchip), p_scl_entry->entry_id,pp_bmp);
            }
        }

        /* add to group entry list's head */
        ctc_list_pointer_insert_head(&(pg->entry_list), &(p_scl_entry->head));

        if (temp_ad.bind_nh)
        {
            _sys_usw_scl_bind_nexthop(lchip, p_scl_entry, temp_ad.nexthop_id);
        }
    }

    return CTC_E_NONE;
}
int32
_sys_usw_scl_wb_sync_igs_hash_entry_func(void* bucket_data, void* user_data)
{
    uint32 max_entry_num = 0;
    sys_scl_sw_entry_t* p_scl_entry    = NULL;
    sys_wb_scl_igs_hash_entry_t*  p_wb_scl_igs_hash_entry = NULL;
    ctc_wb_data_t*           p_wb_data      = NULL;
    sys_scl_flexed_key_t* p_scl_flex_key = NULL;
    sys_scl_sw_block_t*      p_block = NULL;
    uint8                    lchip = 0;
    uint8                    is_default;
    uint8 is_tcam_key,egs_hash_key,igs_hash_key;

    p_scl_entry = (sys_scl_sw_entry_t*)bucket_data;
    p_wb_data   = (ctc_wb_data_t*)(((sys_scl_traverse_data_t*)user_data)->data0);
    p_block   = (sys_scl_sw_block_t*)(((sys_scl_traverse_data_t*)user_data)->data1);
    lchip     = ((sys_scl_traverse_data_t*)user_data)->value0;
    is_default = ((sys_scl_traverse_data_t*)user_data)->value1;

    p_wb_scl_igs_hash_entry = (sys_wb_scl_igs_hash_entry_t*)p_wb_data->buffer + p_wb_data->valid_cnt;
    sal_memset(p_wb_scl_igs_hash_entry, 0, sizeof(sys_wb_scl_igs_hash_entry_t));

    max_entry_num = p_wb_data->buffer_len / sizeof(sys_wb_scl_igs_hash_entry_t);

    is_tcam_key = SCL_ENTRY_IS_TCAM(p_scl_entry->key_type);
    egs_hash_key = !is_tcam_key  && ( SYS_SCL_ACTION_EGRESS == p_scl_entry->action_type);
    igs_hash_key = (!is_tcam_key && !egs_hash_key)|| is_default;

    if(!igs_hash_key)
    {
        return CTC_E_NONE;
    }

    if (p_scl_entry->is_buffer)
    {
        /* uninstall entry not sync, but need to update fpa count for tcam entry
        * need to clear valid bit after restore,so need to store key index for hash entry
        */
        if (!is_default && (SCL_ENTRY_IS_TCAM(p_scl_entry->key_type) || (p_scl_entry->resolve_conflict)))
        {
            uint8 fpa_size =0;
            p_scl_flex_key = (sys_scl_flexed_key_t*)p_scl_entry->u.temp_entry->fk;
            SYS_SCL_ENCODE_XKEY_FPA_SIZE(p_scl_flex_key, p_scl_entry, fpa_size)
            if (p_scl_flex_key && p_scl_flex_key->is_xkey && !p_scl_flex_key->is_replace)
            {
                fpa_size = fpa_size+1;
            }

            (p_block[SCL_ENCODE_BLOCK_ID(p_scl_entry->direction, p_scl_entry->group_priority)].fpab.free_count) += (SYS_SCL_GET_STEP(fpa_size));
            (p_block[SCL_ENCODE_BLOCK_ID(p_scl_entry->direction, p_scl_entry->group_priority)].fpab.sub_free_count[fpa_size])++;

            return CTC_E_NONE;
        }
        else if(is_default || p_scl_entry->hash_valid == 0)
        {
            return CTC_E_NONE;
        }
    }
    CTC_ERROR_RETURN(_sys_usw_scl_wb_mapping_igs_hash_entry(lchip, p_wb_scl_igs_hash_entry, p_scl_entry, 1, is_default));

    if (++p_wb_data->valid_cnt == max_entry_num)
    {
        CTC_ERROR_RETURN(ctc_wb_add_entry(p_wb_data));
        p_wb_data->valid_cnt = 0;
    }

    return CTC_E_NONE;
}

#if 0
int32
_sys_usw_scl_wb_mapping_entry(uint8 lchip, sys_wb_scl_entry_t* p_wb_scl_entry, sys_scl_sw_entry_t* p_scl_entry, uint8 is_sync, uint8 is_default)
{
    uint8  hash_uninstall = 0;
    uint8 vlan_edit_profile_id = 0;
    uint8 flag = 0;/* use sys_scl_sw_entry_tcam_t or sys_scl_sw_entry_t */
    sys_scl_flexed_key_t* p_scl_flex_key = NULL;
    sys_scl_sw_block_t*         pb = NULL;
    sys_scl_sw_igs_ad_t temp_ad;

    sal_memset(&temp_ad, 0, sizeof(sys_scl_sw_igs_ad_t));

    if (is_sync)
    {
        _sys_usw_scl_mapping_ad(p_scl_entry->u.ad, &temp_ad, 1, 0, p_scl_entry->direction);
        p_wb_scl_entry->entry_id             = p_scl_entry->entry_id;
        p_wb_scl_entry->direction            = p_scl_entry->direction;
        p_wb_scl_entry->is_xkey              = p_scl_entry->is_xkey;
        p_wb_scl_entry->action_type          = p_scl_entry->action_type;
        p_wb_scl_entry->resolve_conflict     = p_scl_entry->resolve_conflict;
        p_wb_scl_entry->l3_type              = p_scl_entry->l3_type;
        p_wb_scl_entry->l4_type              = p_scl_entry->l4_type;
        p_wb_scl_entry->is_half              = temp_ad.com.is_half;
        p_wb_scl_entry->rpf_check_en         = temp_ad.rpf_check_en;
        p_wb_scl_entry->uninstall            = p_scl_entry->uninstall;
        p_wb_scl_entry->hash_valid           = p_scl_entry->hash_valid;
        p_wb_scl_entry->key_exist            = p_scl_entry->key_exist;
        p_wb_scl_entry->key_conflict         = p_scl_entry->key_conflict;
        p_wb_scl_entry->u1_type              = temp_ad.com.u1_type;
        p_wb_scl_entry->u2_type              = temp_ad.com.u2_type;
        p_wb_scl_entry->u3_type              = temp_ad.com.u3_type;
        p_wb_scl_entry->u4_type              = temp_ad.com.u4_type;
        p_wb_scl_entry->u5_type              = temp_ad.com.u5_type;
        p_wb_scl_entry->ad_type              = temp_ad.com.ad_type;
        p_wb_scl_entry->is_service_policer   = temp_ad.is_service_policer;
        p_wb_scl_entry->bind_nh              = temp_ad.bind_nh;
        p_wb_scl_entry->vpws_oam_en          = temp_ad.vpws_oam_en;
        p_wb_scl_entry->fwd_type             = temp_ad.fwd_type;

        flag = (SCL_ENTRY_IS_TCAM(p_scl_entry->key_type) || p_scl_entry->resolve_conflict) ? 1: 0;
        p_wb_scl_entry->l2_type              = flag ? ((sys_scl_sw_entry_tcam_t*)p_scl_entry)->l2_type: 0;
        p_wb_scl_entry->l4_user_type         = flag ? ((sys_scl_sw_entry_tcam_t*)p_scl_entry)->l4_user_type: 0;
        p_wb_scl_entry->mac_key_vlan_mode    = flag ? ((sys_scl_sw_entry_tcam_t*)p_scl_entry)->mac_key_vlan_mode: 0;
        p_wb_scl_entry->mac_key_macda_mode   = flag ? ((sys_scl_sw_entry_tcam_t*)p_scl_entry)->mac_key_macda_mode: 0;
        p_wb_scl_entry->key_l4_port_mode     = flag ? ((sys_scl_sw_entry_tcam_t*)p_scl_entry)->key_l4_port_mode: 0;

        /*p_wb_scl_entry->u1_bitmap           = p_scl_entry->u1_bitmap & 0xFFFF;
        p_wb_scl_entry->u1_bitmap_high      = p_scl_entry->u1_bitmap >> 16;
        p_wb_scl_entry->u3_bitmap           = p_scl_entry->u3_bitmap;
        p_wb_scl_entry->u2_bitmap           = p_scl_entry->u2_bitmap & 0xFF;
        p_wb_scl_entry->u2_bitmap_high      = p_scl_entry->u2_bitmap >> 8;
        p_wb_scl_entry->u4_bitmap           = p_scl_entry->u4_bitmap;
        p_wb_scl_entry->u5_bitmap           = p_scl_entry->u5_bitmap & 0xFF;
        p_wb_scl_entry->u5_bitmap_high      = p_scl_entry->u5_bitmap >> 8;*/
        p_wb_scl_entry->userid_bmp          = temp_ad.com.userid_bmp;
        p_wb_scl_entry->fwd_bmp             = temp_ad.com.fwd_bmp;
        p_wb_scl_entry->hash_field_sel_id   = p_scl_entry->hash_field_sel_id;
        p_wb_scl_entry->range_bitmap = flag ? ((sys_scl_sw_entry_tcam_t*)p_scl_entry)->range_bitmap: 0;

        p_wb_scl_entry->nexthop_id           = temp_ad.nexthop_id;
        p_wb_scl_entry->dot1ae_chan_id       = temp_ad.dot1ae_chan_id;
        p_wb_scl_entry->key_type = p_scl_entry->key_type;

        SYS_SCL_COPY_DB_TO_WB(p_wb_scl_entry->key_index, p_scl_entry->key_index);
        SYS_SCL_COPY_DB_TO_WB(p_wb_scl_entry->ad_index, temp_ad.com.ad_index);
        vlan_edit_profile_id = temp_ad.vlan_edit ? temp_ad.vlan_edit->profile_id : 0xFF;
        SYS_SCL_COPY_DB_TO_WB(p_wb_scl_entry->vlan_edit_profile_id, vlan_edit_profile_id);
        /* for tcam entry */
        if (!is_default && (SCL_ENTRY_IS_TCAM(p_scl_entry->key_type) || p_scl_entry->resolve_conflict))
        {
            pb = &p_usw_scl_master[lchip]->fpa_block[SCL_ENCODE_BLOCK_ID(p_scl_entry->direction, p_scl_entry->group->priority)];
            SYS_SCL_COPY_DB_TO_WB(p_wb_scl_entry->priority, pb->fpab.entries[p_scl_entry->key_index]->priority);
        }
        p_wb_scl_entry->policer_id           = temp_ad.policer_id;
        p_wb_scl_entry->vn_id                = temp_ad.vn_id;

        p_wb_scl_entry->group_id             = is_default ? 0 : p_scl_entry->group->group_id;

        p_wb_scl_entry->acl_profile_id = temp_ad.acl_profile ? temp_ad.acl_profile->profile_id : 0xFF;
        p_wb_scl_entry->is_scl         = temp_ad.acl_profile ? temp_ad.acl_profile->is_scl : 0;

        p_wb_scl_entry->ether_type             = flag ? ((sys_scl_sw_entry_tcam_t*)p_scl_entry)->ether_type: 0;
        p_wb_scl_entry->ether_type_index       = flag ? ((sys_scl_sw_entry_tcam_t*)p_scl_entry)->ether_type_index: 0;
        p_wb_scl_entry->service_id           = temp_ad.service_id;
        p_wb_scl_entry->cos_idx           = temp_ad.cos_idx;

        p_wb_scl_entry->acl_profile_valid = 0;
        if(temp_ad.acl_profile)
        {
            p_wb_scl_entry->acl_profile_valid = 1;
        }
        p_wb_scl_entry->aset_level           = p_scl_entry->aset_level;
        sal_memcpy(&p_wb_scl_entry->aset, p_scl_entry->aset, sizeof(sys_scl_aset_t));
        p_wb_scl_entry->key_bmp = p_scl_entry->key_bmp;
    }
    else
    {
        uint8  count_size = 0;
        uint32 cmd   = 0;
        uint32 key_id = 0;
        uint32 act_id = 0;
        uint32 entry_size = 0;
        uint8 fpa_size = 0;
        uint8 igs_hash_key = 0;
        ds_t ad;
        sys_scl_sw_group_t* pg = NULL;
        sys_scl_sp_vlan_edit_t sp_vlan_edit;
        sys_scl_sp_vlan_edit_t* p_sp_vlan_edit = NULL;
        sys_scl_action_acl_t acl;
        sys_scl_action_acl_t* p_acl = NULL;

        sal_memset(&sp_vlan_edit, 0, sizeof(sys_scl_sp_vlan_edit_t));
        sal_memset(&acl, 0, sizeof(sys_scl_action_acl_t));
        sal_memset(&ad, 0, sizeof(ds_t));

        p_scl_entry->entry_id                = p_wb_scl_entry->entry_id;
        p_scl_entry->direction               = p_wb_scl_entry->direction;
        p_scl_entry->action_type             = p_wb_scl_entry->action_type;
        p_scl_entry->resolve_conflict        = p_wb_scl_entry->resolve_conflict;
        p_scl_entry->is_half                 = p_wb_scl_entry->is_half;
        p_scl_entry->uninstall               = p_wb_scl_entry->uninstall;
        p_scl_entry->hash_valid              = p_wb_scl_entry->hash_valid;
        p_scl_entry->key_exist               = p_wb_scl_entry->key_exist;
        p_scl_entry->key_conflict            = p_wb_scl_entry->key_conflict;
        p_scl_entry->l3_type                 = p_wb_scl_entry->l3_type;
        p_scl_entry->l4_type                 = p_wb_scl_entry->l4_type;

        /*p_scl_entry->u1_bitmap               = p_wb_scl_entry->u1_bitmap | (p_wb_scl_entry->u1_bitmap_high << 16);
        p_scl_entry->u3_bitmap               = p_wb_scl_entry->u3_bitmap;
        p_scl_entry->u2_bitmap               = p_wb_scl_entry->u2_bitmap | (p_wb_scl_entry->u2_bitmap_high << 8);
        p_scl_entry->u4_bitmap               = p_wb_scl_entry->u4_bitmap;
        p_scl_entry->u5_bitmap               = p_wb_scl_entry->u5_bitmap | (p_wb_scl_entry->u5_bitmap_high << 8);*/
        p_scl_entry->hash_field_sel_id       = p_wb_scl_entry->hash_field_sel_id;
        //sal_memcpy(p_scl_entry->hash_sel_bmp, p_wb_scl_entry->hash_sel_bmp, sizeof(p_scl_entry->hash_sel_bmp));
        p_scl_entry->is_default              = is_default;

        temp_ad.com.lchip                        = lchip;
        temp_ad.com.action_type                  = p_wb_scl_entry->action_type;
        temp_ad.com.is_half                      = p_wb_scl_entry->is_half;
        temp_ad.rpf_check_en                     = p_wb_scl_entry->rpf_check_en;
        temp_ad.com.u1_type                      = p_wb_scl_entry->u1_type;
        temp_ad.com.u2_type                      = p_wb_scl_entry->u2_type;
        temp_ad.com.u3_type                      = p_wb_scl_entry->u3_type;
        temp_ad.com.u4_type                      = p_wb_scl_entry->u4_type;
        temp_ad.com.u5_type                      = p_wb_scl_entry->u5_type;
        temp_ad.is_service_policer               = p_wb_scl_entry->is_service_policer;
        temp_ad.bind_nh                          = p_wb_scl_entry->bind_nh;
        temp_ad.vpws_oam_en                      = p_wb_scl_entry->vpws_oam_en;
        temp_ad.com.userid_bmp                   = p_wb_scl_entry->userid_bmp;
        temp_ad.com.fwd_bmp                      = p_wb_scl_entry->fwd_bmp;
        temp_ad.com.ad_type                      = p_wb_scl_entry->ad_type;
        temp_ad.nexthop_id                       = p_wb_scl_entry->nexthop_id;
        temp_ad.dot1ae_chan_id                   = p_wb_scl_entry->dot1ae_chan_id;
        temp_ad.fwd_type                         = p_wb_scl_entry->fwd_type;

        p_scl_entry->key_type = p_wb_scl_entry->key_type;
        CTC_ERROR_RETURN(_sys_usw_scl_get_flex_key_node(lchip, p_scl_entry, &p_scl_flex_key));
        if(p_scl_flex_key)
        {
            p_scl_flex_key->entry_count++;
        }

        if (SCL_ENTRY_IS_TCAM(p_scl_entry->key_type)|| p_scl_entry->resolve_conflict)
        {
            ((sys_scl_sw_entry_tcam_t*)p_scl_entry)->l2_type                 = p_wb_scl_entry->l2_type;
            ((sys_scl_sw_entry_tcam_t*)p_scl_entry)->l4_user_type            = p_wb_scl_entry->l4_user_type;
            ((sys_scl_sw_entry_tcam_t*)p_scl_entry)->mac_key_vlan_mode       = p_wb_scl_entry->mac_key_vlan_mode;
            ((sys_scl_sw_entry_tcam_t*)p_scl_entry)->mac_key_macda_mode      = p_wb_scl_entry->mac_key_macda_mode;
            ((sys_scl_sw_entry_tcam_t*)p_scl_entry)->key_l4_port_mode        = p_wb_scl_entry->key_l4_port_mode;
            ((sys_scl_sw_entry_tcam_t*)p_scl_entry)->ether_type             = p_wb_scl_entry->ether_type;
            ((sys_scl_sw_entry_tcam_t*)p_scl_entry)->ether_type_index             = p_wb_scl_entry->ether_type_index;
            ((sys_scl_sw_entry_tcam_t*)p_scl_entry)->range_bitmap             = p_wb_scl_entry->range_bitmap;
        }
        p_scl_entry->aset_level           = p_wb_scl_entry->aset_level;
        MALLOC_ZERO(MEM_SCL_MODULE, p_scl_entry->aset, sizeof(sys_scl_aset_t));
        sal_memcpy(p_scl_entry->aset, &p_wb_scl_entry->aset, sizeof(sys_scl_aset_t));

        p_scl_entry->key_index = SYS_SCL_WB_DATA(p_wb_scl_entry->key_index);
        temp_ad.com.ad_index = SYS_SCL_WB_DATA(p_wb_scl_entry->ad_index);
        vlan_edit_profile_id = SYS_SCL_WB_DATA(p_wb_scl_entry->vlan_edit_profile_id);
        if (0xFF != vlan_edit_profile_id)
        {
            cmd = DRV_IOR(DsVlanActionProfile_t, DRV_ENTRY_FLAG);
            CTC_ERROR_RETURN(DRV_IOCTL(lchip, vlan_edit_profile_id, DRV_CMD_BMP_EN(cmd, MCHIP_FEATURE_PP_EN(lchip,CTC_FEATURE_SCL)), &sp_vlan_edit.action_profile));
            sp_vlan_edit.profile_id = vlan_edit_profile_id;
            CTC_ERROR_RETURN(ctc_spool_add(p_usw_scl_master[lchip]->vlan_edit_spool, &sp_vlan_edit, NULL, &p_sp_vlan_edit));
            temp_ad.vlan_edit = p_sp_vlan_edit;
            temp_ad.vlan_profile_id = vlan_edit_profile_id;
        }
        temp_ad.policer_id              = p_wb_scl_entry->policer_id;
        temp_ad.vn_id                   = p_wb_scl_entry->vn_id;

        p_scl_entry->key_bmp = p_wb_scl_entry->key_bmp;

        temp_ad.service_id              = p_wb_scl_entry->service_id;
        temp_ad.cos_idx                 = p_wb_scl_entry->cos_idx;

        if(!is_default)
        {
            _sys_usw_scl_get_group_by_gid(lchip, p_wb_scl_entry->group_id, &pg);
            p_scl_entry->group                   = pg;
            /* restore entry count by different action type, this count is used for spec limit */
            _sys_usw_scl_get_table_id(lchip, pg->priority, p_scl_entry, &key_id, &act_id);
        }
        /*Only hash uninstalled entry need to clear valid bit*/
        hash_uninstall = p_scl_entry->uninstall && !is_default;
        if(hash_uninstall && p_scl_entry->hash_valid)
        {
            int32 ret = 0;
            drv_acc_in_t in;
            drv_acc_out_t out;
            uint32 pu32[MAX_ENTRY_WORD] = { 0 };

            sal_memset(&in, 0, sizeof(in));
            sal_memset(&out, 0, sizeof(out));

            drv_set_warmboot_status(lchip, DRV_WB_STATUS_DONE);
            in.type = DRV_ACC_TYPE_ADD;
            in.op_type = DRV_ACC_OP_BY_INDEX;
            in.tbl_id = key_id;
            drv_acc_get_hash_module(lchip,in.tbl_id, &in.module);
            in.data   = &pu32;
            in.index  = p_scl_entry->key_index;
            in.oper_bmp = DRV_ACC_BMP_EN(MCHIP_FEATURE_PP_EN(lchip, CTC_FEATURE_SCL));
            drv_acc_api(lchip, &in, &out);
            drv_set_warmboot_status(lchip, DRV_WB_STATUS_RELOADING);
            return ret;
        }
        CTC_ERROR_RETURN(sys_usw_ftm_query_table_entry_size(lchip, key_id, &entry_size));
        count_size = entry_size / SCL_KEY_USW_SIZE_80;
        count_size =    !p_scl_entry->resolve_conflict ? count_size :
                        p_scl_entry->direction == CTC_INGRESS ? count_size : (count_size*2);
        if (!is_default && ((!SCL_ENTRY_IS_TCAM(p_scl_entry->key_type) && !p_scl_entry->resolve_conflict) || (p_scl_entry->resolve_conflict && DRV_FROM_TMM(lchip))))
        {
            p_usw_scl_master[lchip]->entry_count[p_scl_entry->action_type==SYS_SCL_ACTION_EGRESS && pg->priority == 1? SYS_SCL_ACTION_EGRESS1: p_scl_entry->action_type] += count_size;
        }

        /* restore hash field select count */
        if (((SYS_SCL_KEY_HASH_L2 == p_scl_entry->key_type) || (SYS_SCL_KEY_HASH_L2_UDF == p_scl_entry->key_type) || (SYS_SCL_KEY_HASH_L3_UDF == p_scl_entry->key_type)) && !is_default)
        {
            p_usw_scl_master[lchip]->hash_sel_profile_count[p_scl_entry->hash_field_sel_id] += 1;
        }

        /* 0 is reasonable */
        if (p_wb_scl_entry->acl_profile_valid)
        {
            if (p_wb_scl_entry->is_scl)
            {
                cmd = DRV_IOR(DsSclAclControlProfile_t, DRV_ENTRY_FLAG);
                CTC_ERROR_RETURN(DRV_IOCTL(lchip, p_wb_scl_entry->acl_profile_id, DRV_CMD_BMP_EN(cmd,
                                  MCHIP_FEATURE_PP_EN(lchip,CTC_FEATURE_SCL)), &acl.acl_control_profile));
                acl.is_scl = 1;
                acl.profile_id = p_wb_scl_entry->acl_profile_id;
                CTC_ERROR_RETURN(ctc_spool_add(p_usw_scl_master[lchip]->acl_spool, &acl, NULL, &p_acl));
            }
            else
            {
                cmd = DRV_IOR(DsTunnelAclControlProfile_t, DRV_ENTRY_FLAG);
                CTC_ERROR_RETURN(DRV_IOCTL(lchip, p_wb_scl_entry->acl_profile_id, DRV_CMD_BMP_EN(cmd,
                                  MCHIP_FEATURE_PP_EN(lchip,CTC_FEATURE_SCL)), &acl.acl_control_profile));
                acl.is_scl = 0;
                acl.profile_id = p_wb_scl_entry->acl_profile_id;
                CTC_ERROR_RETURN(ctc_spool_add(p_usw_scl_master[lchip]->acl_spool, &acl, NULL, &p_acl));
            }
            temp_ad.acl_profile = p_acl;
            temp_ad.acl_profile_id = acl.profile_id;
        }
        if(is_default || (hash_uninstall && p_scl_entry->key_index == 0xFFFF))
        {
            return CTC_E_NONE;
        }
        if(p_wb_scl_entry->ether_type != 0)
        {
            CTC_ERROR_RETURN(MCHIP_SCL(lchip)->add_compress_ether_type(lchip, ((sys_scl_sw_entry_tcam_t*)p_scl_entry)->ether_type, 0, NULL, &ether_type_index));
            ((sys_scl_sw_entry_tcam_t*)p_scl_entry)->ether_type_index = ether_type_index;
        }

        /* for hash entry */
        if (SYS_SCL_IS_INNER_ENTRY(p_wb_scl_entry->entry_id) && !SCL_ENTRY_IS_TCAM(p_wb_scl_entry->key_type) && !p_wb_scl_entry->resolve_conflict)
        {
            sys_scl_hash_key_entry_t* hash_entry;               /* when do hash insert, the data to inserted must be a pointer */
            if (SYS_SCL_ACTION_EGRESS != p_wb_scl_entry->action_type)
            {
                temp_ad.com.action_type = p_wb_scl_entry->action_type;
                temp_ad.com.is_half = p_scl_entry->is_half;
                temp_ad.com.priority = (1 == p_usw_scl_master[lchip]->hash_mode ? pg->priority : 0);

                CTC_MAX_VALUE_CHECK(temp_ad.com.priority, 1);
                igs_hash_key = !(SCL_ENTRY_IS_TCAM(p_scl_entry->key_type) || p_scl_entry->resolve_conflict) && (SYS_SCL_ACTION_EGRESS != p_scl_entry->action_type);
                _sys_usw_scl_mapping_ad(&ad, &temp_ad, 0, igs_hash_key, p_scl_entry->direction);
                CTC_ERROR_RETURN(ctc_spool_add(p_usw_scl_master[lchip]->ad_spool[temp_ad.com.priority*SYS_SCL_SW_AD_TYPE_IGS_MAX+temp_ad.com.ad_type], &ad, NULL, &p_scl_entry->u.ad));
            }
            MALLOC_ZERO(MEM_SCL_MODULE, hash_entry, sizeof(sys_scl_hash_key_entry_t));
            if (NULL == hash_entry)
            {
                SYS_SCL_DBG_OUT(CTC_DEBUG_LEVEL_ERROR, " No memory \n");
                return CTC_E_NO_MEMORY;

            }
            hash_entry->action_type = p_wb_scl_entry->action_type;
            hash_entry->entry_id = p_wb_scl_entry->entry_id;
            hash_entry->scl_id = p_scl_entry->group->priority;
            hash_entry->key_index = p_scl_entry->key_index;

            /* add to hash by key */
            if (NULL == ctc_hash_insert(p_usw_scl_master[lchip]->hash_key_entry, hash_entry))
            {
                SYS_SCL_DBG_OUT(CTC_DEBUG_LEVEL_ERROR, " [SCL] Hash insert fail\n");
                mem_free(hash_entry);
                return CTC_E_NO_MEMORY;
            }
        }
        else
        {
            sys_scl_sw_tcam_entry_t* pe_tcam = NULL;
            MALLOC_ZERO(MEM_SCL_MODULE, pe_tcam, sizeof(sys_scl_sw_tcam_entry_t));
            if (NULL == pe_tcam)
            {
                SYS_SCL_DBG_OUT(CTC_DEBUG_LEVEL_ERROR, " No memory \n");
                return CTC_E_NO_MEMORY;

            }
            pe_tcam->fpae.entry_id = p_wb_scl_entry->entry_id;
            pe_tcam->fpae.offset_a = p_scl_entry->key_index;
            pe_tcam->fpae.priority = SYS_SCL_WB_DATA(p_wb_scl_entry->priority);
            SYS_SCL_ENCODE_XKEY_FPA_SIZE(p_scl_flex_key, p_wb_scl_entry, fpa_size)
            pe_tcam->fpae.step = SYS_SCL_GET_STEP(p_usw_scl_master[lchip]->fpa_size[p_wb_scl_entry->key_type]);
            pe_tcam->fpae.flag = !(p_wb_scl_entry->uninstall);
            pe_tcam->entry = p_scl_entry;
            pb = &p_usw_scl_master[lchip]->fpa_block[SCL_ENCODE_BLOCK_ID(p_wb_scl_entry->direction, pg->priority)];
            pb->fpab.entries[p_scl_entry->key_index] = &pe_tcam->fpae;
        }

        /* for inner entry need to restore entry-id-opf */
        if(SCL_INNER_ENTRY_ID(p_scl_entry->entry_id))
        {
            sys_usw_opf_t opf;
            sal_memset(&opf, 0, sizeof(sys_usw_opf_t));
            opf.pool_index = 0;
            opf.pool_type  = p_usw_scl_master[lchip]->opf_type_entry_id;

            sys_usw_opf_alloc_offset_from_position(lchip, &opf, 1, (p_scl_entry->entry_id - SYS_SCL_MIN_INNER_ENTRY_ID));
            if (SCL_ENTRY_IS_TCAM(p_wb_scl_entry->key_type) || p_wb_scl_entry->resolve_conflict)
            {
                sys_scl_tcam_entry_key_t* tcam_entry;               /* when do hash insert, the data to inserted must be a pointer */
                uint8 loop = 0;
                tbl_entry_t          entry;
                uint32      hw_key_index  = 0;
                uint32      hw_ad_index   = 0;

                MALLOC_ZERO(MEM_SCL_MODULE, tcam_entry, sizeof(sys_scl_tcam_entry_key_t));
                if (NULL == tcam_entry)
                {
                    SYS_SCL_DBG_OUT(CTC_DEBUG_LEVEL_ERROR, " No memory \n");
                    return CTC_E_NO_MEMORY;
                }
                entry.data_entry = tcam_entry->key;
                entry.mask_entry = tcam_entry->mask;
                cmd = DRV_IOR(key_id, DRV_ENTRY_FLAG);
                _sys_usw_scl_get_index(lchip, key_id, p_scl_entry, &hw_key_index, &hw_ad_index);
                DRV_IOCTL(lchip, hw_key_index, DRV_CMD_BMP_EN(cmd, MCHIP_FEATURE_PP_EN(lchip,CTC_FEATURE_SCL)), &entry);

                for(loop = 0; loop < SYS_SCL_MAX_KEY_SIZE_IN_WORD; loop++)
                {
                    tcam_entry->key[loop] = tcam_entry->key[loop] & tcam_entry->mask[loop];
                }
                tcam_entry->scl_id = p_scl_entry->group->priority;
                tcam_entry->p_entry = p_scl_entry;

                /* add to hash by key */
                if (NULL == ctc_hash_insert(p_usw_scl_master[lchip]->tcam_entry_by_key, tcam_entry))
                {
                    mem_free(tcam_entry);
                    SYS_SCL_DBG_OUT(CTC_DEBUG_LEVEL_ERROR, " [SCL] Hash insert fail\n");
                    return CTC_E_NO_MEMORY;
                }
            }
        }

        /* add to group entry list's head */
        ctc_list_pointer_insert_head(&(pg->entry_list), &(p_scl_entry->head));

        if (temp_ad.bind_nh)
        {
            _sys_usw_scl_bind_nexthop(lchip, p_scl_entry, temp_ad.nexthop_id);
        }

    }

    return CTC_E_NONE;
}

int32
_sys_usw_scl_wb_sync_entry_func(void* bucket_data, void* user_data)
{
    uint32 max_entry_num = 0;
    sys_scl_sw_entry_t* p_scl_entry    = NULL;
    sys_wb_scl_entry_t*   p_wb_scl_entry = NULL;
    ctc_wb_data_t*           p_wb_data      = NULL;
    sys_scl_flexed_key_t* p_scl_flex_key = NULL;
    sys_scl_sw_block_t*      p_block = NULL;
    uint8                    lchip = 0;
    uint8                    is_default;

    p_scl_entry = (sys_scl_sw_entry_t*)bucket_data;
    p_wb_data   = (ctc_wb_data_t*)(((sys_scl_traverse_data_t*)user_data)->data0);
    p_block   = (sys_scl_sw_block_t*)(((sys_scl_traverse_data_t*)user_data)->data1);
    lchip     = ((sys_scl_traverse_data_t*)user_data)->value0;
    is_default = ((sys_scl_traverse_data_t*)user_data)->value1;

    p_wb_scl_entry = (sys_wb_scl_entry_t*)p_wb_data->buffer + p_wb_data->valid_cnt;
    sal_memset(p_wb_scl_entry, 0, sizeof(sys_wb_scl_entry_t));

    max_entry_num = p_wb_data->buffer_len / sizeof(sys_wb_scl_entry_t);

    if (p_scl_entry->is_buffer)
    {
         /* uninstall entry not sync, but need to update fpa count for tcam entry
          * need to clear valid bit after restore,so need to store key index for hash entry
          */
        if (!is_default && (SCL_ENTRY_IS_TCAM(p_scl_entry->key_type) || (p_scl_entry->resolve_conflict)))
        {
            uint8 fpa_size =0;
            p_scl_flex_key = (sys_scl_flexed_key_t*)p_scl_entry->u.temp_entry->fk;
            SYS_SCL_ENCODE_XKEY_FPA_SIZE(p_scl_flex_key, p_scl_entry, fpa_size)
            if (p_scl_flex_key && p_scl_flex_key->is_xkey && !p_scl_flex_key->is_replace)
            {
                fpa_size = fpa_size+1;
            }

            (p_block[SCL_ENCODE_BLOCK_ID(p_scl_entry->direction, p_scl_entry->group->priority)].fpab.free_count) += (SYS_SCL_GET_STEP(fpa_size));
            (p_block[SCL_ENCODE_BLOCK_ID(p_scl_entry->direction, p_scl_entry->group->priority)].fpab.sub_free_count[fpa_size])++;

            return CTC_E_NONE;
        }
        else if(is_default || p_scl_entry->hash_valid == 0)
        {
            return CTC_E_NONE;
        }
    }

    CTC_ERROR_RETURN(_sys_usw_scl_wb_mapping_entry(lchip, p_wb_scl_entry, p_scl_entry, 1, is_default));
    if (++p_wb_data->valid_cnt == max_entry_num)
    {
        CTC_ERROR_RETURN(ctc_wb_add_entry(p_wb_data));
        p_wb_data->valid_cnt = 0;
    }

    return CTC_E_NONE;

}
#endif
#if 0
int32
_sys_usw_scl_wb_mapping_entry_by_key(sys_wb_scl_hash_key_entry_t* p_wb_scl_entry_by_key, sys_scl_hash_key_entry_t* p_scl_entry_by_key, uint8 is_sync)
{
    if(is_sync)
    {
        p_wb_scl_entry_by_key->key_index = p_scl_entry_by_key->key_index;
        p_wb_scl_entry_by_key->action_type = p_scl_entry_by_key->action_type;
        p_wb_scl_entry_by_key->entry_id = p_scl_entry_by_key->entry_id;
        p_wb_scl_entry_by_key->scl_id = p_scl_entry_by_key->scl_id;
    }
    else
    {
        p_scl_entry_by_key->key_index = p_wb_scl_entry_by_key->key_index;
        p_scl_entry_by_key->action_type = p_wb_scl_entry_by_key->action_type;
        p_scl_entry_by_key->entry_id = p_wb_scl_entry_by_key->entry_id;
        p_scl_entry_by_key->scl_id = p_wb_scl_entry_by_key->scl_id;
    }
    return CTC_E_NONE;
}
#endif

#if 0
int32
_sys_usw_scl_wb_sync_entry_by_key_func(void* bucket_data, void* user_data)
{
    uint32 max_entry_num = 0;
    sys_scl_hash_key_entry_t* p_scl_entry_by_key    = NULL;
    sys_wb_scl_hash_key_entry_t*   p_wb_scl_entry_by_key = NULL;
    ctc_wb_data_t*                 p_wb_data      = NULL;

    p_scl_entry_by_key = (sys_scl_hash_key_entry_t*)bucket_data;
    p_wb_data   = (ctc_wb_data_t*)user_data;

    p_wb_scl_entry_by_key = (sys_wb_scl_hash_key_entry_t*)p_wb_data->buffer + p_wb_data->valid_cnt;
    sal_memset(p_wb_scl_entry_by_key, 0, sizeof(sys_wb_scl_hash_key_entry_t));

    max_entry_num = p_wb_data->buffer_len / sizeof(sys_wb_scl_hash_key_entry_t);

    CTC_ERROR_RETURN(_sys_usw_scl_wb_mapping_entry_by_key(p_wb_scl_entry_by_key, p_scl_entry_by_key, 1));
    if (++p_wb_data->valid_cnt == max_entry_num)
    {
        CTC_ERROR_RETURN(ctc_wb_add_entry(p_wb_data));
        p_wb_data->valid_cnt = 0;
    }

    return CTC_E_NONE;

}
#endif

#if 0
int32
_sys_usw_scl_wb_mapping_tcam_entry_by_key(sys_wb_scl_tcam_key_entry_t* p_wb_scl_tcam_entry_by_key, sys_scl_tcam_entry_key_t* p_scl_tcam_entry_by_key, uint8 is_sync)
{
    if(is_sync)
    {
        p_wb_scl_tcam_entry_by_key->lchip = p_scl_tcam_entry_by_key->p_entry->lchip;
        p_wb_scl_tcam_entry_by_key->scl_id = p_scl_tcam_entry_by_key->scl_id;
        p_wb_scl_tcam_entry_by_key->entry_id = p_scl_tcam_entry_by_key->p_entry->entry_id;
        sal_memcpy(p_wb_scl_tcam_entry_by_key->key, p_scl_tcam_entry_by_key->key, SYS_SCL_MAX_KEY_SIZE_IN_WORD * 4);
        sal_memcpy(p_wb_scl_tcam_entry_by_key->mask, p_scl_tcam_entry_by_key->mask, SYS_SCL_MAX_KEY_SIZE_IN_WORD * 4);
    }
    else
    {
        uint8 lchip;
        sys_scl_sw_entry_t pe;
        sys_scl_sw_entry_t* pe_lkup = NULL;
        sal_memset(&pe, 0, sizeof(sys_scl_sw_entry_t));
        lchip = p_wb_scl_tcam_entry_by_key->lchip;
        p_scl_tcam_entry_by_key->scl_id = p_wb_scl_tcam_entry_by_key->scl_id;
        sal_memcpy(p_scl_tcam_entry_by_key->key, p_wb_scl_tcam_entry_by_key->key, SYS_SCL_MAX_KEY_SIZE_IN_WORD * 4);
        sal_memcpy(p_scl_tcam_entry_by_key->mask, p_wb_scl_tcam_entry_by_key->mask, SYS_SCL_MAX_KEY_SIZE_IN_WORD * 4);
        pe.entry_id = p_wb_scl_tcam_entry_by_key->entry_id;

        pe_lkup = ctc_hash_lookup(p_usw_scl_master[lchip]->entry, &pe);
        if(!pe_lkup)
        {
            return CTC_E_NOT_EXIST;
        }
        p_scl_tcam_entry_by_key->p_entry = pe_lkup;

    }
    return CTC_E_NONE;
}
#endif

#if 0
int32
_sys_usw_scl_wb_sync_tcam_entry_by_key_func(void* bucket_data, void* user_data)
{
    uint32 max_entry_num = 0;
    sys_scl_tcam_entry_key_t* p_scl_tcam_entry_by_key    = NULL;
    sys_wb_scl_tcam_key_entry_t*   p_wb_scl_tcam_entry_by_key = NULL;
    ctc_wb_data_t*                 p_wb_data      = NULL;

    p_scl_tcam_entry_by_key = (sys_scl_tcam_entry_key_t*)bucket_data;
    p_wb_data   = (ctc_wb_data_t*)user_data;

    p_wb_scl_tcam_entry_by_key = (sys_wb_scl_tcam_key_entry_t*)p_wb_data->buffer + p_wb_data->valid_cnt;
    sal_memset(p_wb_scl_tcam_entry_by_key, 0, sizeof(sys_wb_scl_tcam_key_entry_t));

    max_entry_num = p_wb_data->buffer_len / sizeof(sys_wb_scl_tcam_key_entry_t);

    CTC_ERROR_RETURN(_sys_usw_scl_wb_mapping_tcam_entry_by_key(p_wb_scl_tcam_entry_by_key, p_scl_tcam_entry_by_key, 1));
    if (++p_wb_data->valid_cnt == max_entry_num)
    {
        CTC_ERROR_RETURN(ctc_wb_add_entry(p_wb_data));
        p_wb_data->valid_cnt = 0;
    }

    return CTC_E_NONE;
}
#endif

int32
_sys_usw_scl_wb_restor_range_info(void* bucket_data, void* user_data)
{
    int32 ret = CTC_E_NONE;
    ParserRangeOpCtl_m range_ctl;
    uint8 step = 0, lchip;
    uint16 range_bitmap = 0;
    uint32 cmd;
    uint8 range_id = 0;

    range_bitmap = ((sys_scl_sw_entry_tcam_t*)bucket_data)->range_bitmap;
    lchip = *((uint8*)user_data);

    cmd = DRV_IOR(ParserRangeOpCtl_t, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, DRV_CMD_BMP_EN(cmd, MCHIP_FEATURE_PP_EN(lchip,CTC_FEATURE_SCL)), &range_ctl));

    step = ParserRangeOpCtl_array_1_maxValue_f - ParserRangeOpCtl_array_0_maxValue_f;
    for(range_id = 0; range_id < 12; range_id++)
    {
        if(CTC_IS_BIT_SET(range_bitmap, range_id))
        {
            uint8 type = GetParserRangeOpCtl(V, array_0_opType_f + step * range_id, &range_ctl);
            uint32 min = GetParserRangeOpCtl(V, array_0_minValue_f + step * range_id, &range_ctl);
            uint32 max = GetParserRangeOpCtl(V, array_0_maxValue_f + step * range_id, &range_ctl);
            CTC_ERROR_RETURN(sys_usw_acl_build_field_range(lchip, CTC_INGRESS, type, min, max, &range_bitmap, 1));
        }
    }
    return ret;
}

int32
_sys_usw_scl_wb_mapping_flex_key(uint8 lchip, sys_wb_scl_flex_key_t* p_wb_scl_flexed_key, sys_scl_flexed_key_t* p_scl_flexed_key, uint8 is_sync)
{
    if (is_sync)
    {
        p_wb_scl_flexed_key->key_type        = p_scl_flexed_key->key_type;
        p_wb_scl_flexed_key->origin_key_type = p_scl_flexed_key->origin_key_type;
        p_wb_scl_flexed_key->dir             = p_scl_flexed_key->dir;
        p_wb_scl_flexed_key->key_size        = p_scl_flexed_key->key_size;
        p_wb_scl_flexed_key->is_xkey         = p_scl_flexed_key->is_xkey;
        p_wb_scl_flexed_key->is_replace         = p_scl_flexed_key->is_replace;
        sal_memcpy(p_wb_scl_flexed_key->kset.w,p_scl_flexed_key->kset.w,CTC_B2W_SIZE(CTC_FIELD_KEY_NUM) * sizeof(uint32));
    }
    else
    {
        p_scl_flexed_key->key_type        = p_wb_scl_flexed_key->key_type;
        p_scl_flexed_key->origin_key_type = p_wb_scl_flexed_key->origin_key_type;
        p_scl_flexed_key->dir             = p_wb_scl_flexed_key->dir;
        p_scl_flexed_key->key_size           = p_wb_scl_flexed_key->key_size;
        p_scl_flexed_key->is_xkey           = p_wb_scl_flexed_key->is_xkey;
        p_scl_flexed_key->is_replace           = p_wb_scl_flexed_key->is_replace;
        sal_memcpy(&p_scl_flexed_key->kset.w,p_wb_scl_flexed_key->kset.w,CTC_B2W_SIZE(CTC_FIELD_KEY_NUM) * sizeof(uint32));
    }
    return CTC_E_NONE;
}

int32
_sys_usw_scl_wb_sync_flex_key_func(void* bucket_data, void* user_data)
{
    uint32 max_entry_num = 0;
    uint8 lchip = 0;
    ctc_wb_data_t* p_wb_data = NULL;
    sys_scl_flexed_key_t* p_scl_flexed_key = NULL;
    sys_wb_scl_flex_key_t* p_wb_scl_flexed_key = NULL;

    p_scl_flexed_key = (sys_scl_flexed_key_t*)bucket_data;
    p_wb_data = (ctc_wb_data_t*)(((sys_scl_traverse_data_t*)user_data)->data0);
    lchip = ((sys_scl_traverse_data_t*)user_data)->value0;

    max_entry_num = p_wb_data->buffer_len / sizeof(sys_wb_scl_flex_key_t);
    p_wb_scl_flexed_key = (sys_wb_scl_flex_key_t*)p_wb_data->buffer + p_wb_data->valid_cnt;
    sal_memset(p_wb_scl_flexed_key, 0, sizeof(sys_wb_scl_flex_key_t));

    CTC_ERROR_RETURN(_sys_usw_scl_wb_mapping_flex_key(lchip, p_wb_scl_flexed_key, p_scl_flexed_key, 1));
    if (++p_wb_data->valid_cnt == max_entry_num)
    {
        CTC_ERROR_RETURN(ctc_wb_add_entry(p_wb_data));
        p_wb_data->valid_cnt = 0;
    }

    return CTC_E_NONE;

}

int32

sys_usw_scl_wb_sync(uint8 lchip, uint32 app_id)
{
    uint16 loop1 = 0;
    uint16 loop2 = 0;
    int32  ret   = CTC_E_NONE;
    uint32 max_entry_num = 0;
    ctc_wb_data_t wb_data;
    sys_wb_scl_master_t* p_wb_scl_master = NULL;
    sys_scl_sw_block_t *block;
    sys_scl_traverse_data_t    user_data;


    MALLOC_ZERO(MEM_SCL_MODULE, block, sizeof(sys_scl_sw_block_t)*SCL_TCAM_NUM);
    CTC_ERROR_RETURN(NULL == block ? CTC_E_NO_MEMORY: CTC_E_NONE);

    /* sync up scl_matser */
    CTC_WB_ALLOC_BUFFER(&wb_data.buffer);

    SYS_SCL_LOCK(lchip);
    sal_memcpy(block, p_usw_scl_master[lchip]->fpa_block, MCHIP_CAP(SYS_CAP_SCL_TCAM_NUM) * sizeof(sys_scl_sw_block_t));
# if 0
    if (app_id == 0 || CTC_WB_SUBID(app_id) == SYS_WB_APPID_SCL_SUBID_ENTRY)
    {
        /* sync entry info */
        CTC_WB_INIT_DATA_T((&wb_data), sys_wb_scl_entry_t, CTC_FEATURE_SCL, SYS_WB_APPID_SCL_SUBID_ENTRY);

        user_data.data0 = (void*)&wb_data;
        user_data.data1 = (void*)block;
        user_data.value0 = lchip;
        user_data.value1 = 0;

        CTC_ERROR_GOTO(ctc_hash_traverse(p_usw_scl_master[lchip]->entry, _sys_usw_scl_wb_sync_entry_func, (void*)(&user_data)), ret, done);
        if (wb_data.valid_cnt > 0)
        {
            CTC_ERROR_GOTO(ctc_wb_add_entry(&wb_data), ret, done);
            wb_data.valid_cnt = 0;
        }
        CTC_WB_SYNC_END_DATA(CTC_FEATURE_SCL, SYS_WB_APPID_SCL_SUBID_ENTRY);
    }
#endif
    if (app_id == 0 || CTC_WB_SUBID(app_id) == SYS_WB_APPID_SCL_SUBID_IGS_HASH_ENTRY)
    {
        /* sync entry info */
        CTC_WB_INIT_DATA_T((&wb_data), sys_wb_scl_igs_hash_entry_t, CTC_FEATURE_SCL, SYS_WB_APPID_SCL_SUBID_IGS_HASH_ENTRY);
        user_data.data0 = (void*)&wb_data;
        user_data.data1 = (void*)block;
        user_data.value0 = lchip;
        user_data.value1 = 0;

        CTC_ERROR_GOTO(ctc_hash_traverse(p_usw_scl_master[lchip]->entry, _sys_usw_scl_wb_sync_igs_hash_entry_func, (void*)(&user_data)), ret, done);
        if (wb_data.valid_cnt > 0)
        {
            CTC_ERROR_GOTO(ctc_wb_add_entry(&wb_data), ret, done);
            wb_data.valid_cnt = 0;
        }
        CTC_WB_SYNC_END_DATA(CTC_FEATURE_SCL, SYS_WB_APPID_SCL_SUBID_IGS_HASH_ENTRY);
    }
    if (app_id == 0 || CTC_WB_SUBID(app_id) == SYS_WB_APPID_SCL_SUBID_IGS_TCAM_ENTRY)
    {
        /* sync entry info */
        CTC_WB_INIT_DATA_T((&wb_data), sys_wb_scl_igs_tcam_entry_t, CTC_FEATURE_SCL, SYS_WB_APPID_SCL_SUBID_IGS_TCAM_ENTRY);
        user_data.data0 = (void*)&wb_data;
        user_data.data1 = (void*)block;
        user_data.value0 = lchip;
        user_data.value1 = 0;

        CTC_ERROR_GOTO(ctc_hash_traverse(p_usw_scl_master[lchip]->entry, _sys_usw_scl_wb_sync_igs_tcam_entry_func, (void*)(&user_data)), ret, done);
        if (wb_data.valid_cnt > 0)
        {
            CTC_ERROR_GOTO(ctc_wb_add_entry(&wb_data), ret, done);
            wb_data.valid_cnt = 0;
        }
        CTC_WB_SYNC_END_DATA(CTC_FEATURE_SCL, SYS_WB_APPID_SCL_SUBID_IGS_TCAM_ENTRY);
    }
   if (app_id == 0 || CTC_WB_SUBID(app_id) == SYS_WB_APPID_SCL_SUBID_EGS_HASH_ENTRY)
    {
        /* sync entry info */
        CTC_WB_INIT_DATA_T((&wb_data), sys_wb_scl_egs_entry_t, CTC_FEATURE_SCL, SYS_WB_APPID_SCL_SUBID_EGS_HASH_ENTRY);
        user_data.data0 = (void*)&wb_data;
        user_data.data1 = (void*)block;
        user_data.value0 = lchip;
        user_data.value1 = 0;

        CTC_ERROR_GOTO(ctc_hash_traverse(p_usw_scl_master[lchip]->entry, _sys_usw_scl_wb_sync_egs_hash_entry_func, (void*)(&user_data)), ret, done);
        if (wb_data.valid_cnt > 0)
        {
            CTC_ERROR_GOTO(ctc_wb_add_entry(&wb_data), ret, done);
            wb_data.valid_cnt = 0;
        }
        CTC_WB_SYNC_END_DATA(CTC_FEATURE_SCL, SYS_WB_APPID_SCL_SUBID_EGS_HASH_ENTRY);
    }
    if (app_id == 0 || CTC_WB_SUBID(app_id) == SYS_WB_APPID_SCL_SUBID_MASTER)
    {
        CTC_WB_INIT_DATA_T((&wb_data), sys_wb_scl_master_t, CTC_FEATURE_SCL, SYS_WB_APPID_SCL_SUBID_MASTER);

        max_entry_num = wb_data.buffer_len / sizeof(sys_wb_scl_master_t);

        for (loop1 = 0; loop1 < MCHIP_CAP(SYS_CAP_SCL_TCAM_NUM); loop1++)
        {
            for (loop2 = 0; loop2 < CTC_FPA_KEY_SIZE_NUM; loop2++)
            {
                p_wb_scl_master = (sys_wb_scl_master_t*)wb_data.buffer + wb_data.valid_cnt;
                sal_memset(p_wb_scl_master, 0, sizeof(sys_wb_scl_master_t));
                p_wb_scl_master->lchip = lchip;
                p_wb_scl_master->block_id = loop1;
                p_wb_scl_master->key_size_type = loop2;
                p_wb_scl_master->start_offset = block[loop1].fpab.start_offset[loop2];
                p_wb_scl_master->sub_entry_count = block[loop1].fpab.sub_entry_count[loop2];
                p_wb_scl_master->sub_free_count = block[loop1].fpab.sub_free_count[loop2];
                p_wb_scl_master->version = SYS_WB_VERSION_SCL;

                if (++wb_data.valid_cnt == max_entry_num)
                {
                    CTC_ERROR_GOTO(ctc_wb_add_entry(&wb_data), ret, done);
                    wb_data.valid_cnt = 0;
                }
            }
        }
        if (wb_data.valid_cnt > 0)
        {
            CTC_ERROR_GOTO(ctc_wb_add_entry(&wb_data), ret, done);
            wb_data.valid_cnt = 0;
        }
        CTC_WB_SYNC_END_DATA(CTC_FEATURE_SCL, SYS_WB_APPID_SCL_SUBID_MASTER);
    }
    if (app_id == 0 || CTC_WB_SUBID(app_id) == SYS_WB_APPID_SCL_SUBID_GROUP)
    {
        /* sync group info */
        CTC_WB_INIT_DATA_T((&wb_data), sys_wb_scl_group_t, CTC_FEATURE_SCL, SYS_WB_APPID_SCL_SUBID_GROUP);

        CTC_ERROR_GOTO(ctc_hash_traverse(p_usw_scl_master[lchip]->group, _sys_usw_scl_wb_sync_group_func, (void*)(&wb_data)), ret, done);
        if (wb_data.valid_cnt > 0)
        {
            CTC_ERROR_GOTO(ctc_wb_add_entry(&wb_data), ret, done);
            wb_data.valid_cnt = 0;
        }
        CTC_WB_SYNC_END_DATA(CTC_FEATURE_SCL, SYS_WB_APPID_SCL_SUBID_GROUP);
    }

    if (app_id == 0 || CTC_WB_SUBID(app_id) == SYS_WB_APPID_SCL_SUBID_DEFAULT_ENTRY)
    {
        CTC_WB_INIT_DATA_T((&wb_data), sys_wb_scl_igs_hash_entry_t, CTC_FEATURE_SCL, SYS_WB_APPID_SCL_SUBID_DEFAULT_ENTRY);
        user_data.data0 = (void*)&wb_data;
        user_data.data1 = (void*)block;
        user_data.value0 = lchip;
        user_data.value1 = 1;
        CTC_ERROR_GOTO(ctc_vector_traverse(p_usw_scl_master[lchip]->default_entry, _sys_usw_scl_wb_sync_igs_hash_entry_func, (void*)&user_data), ret, done);
        if (wb_data.valid_cnt > 0)
        {
            CTC_ERROR_GOTO(ctc_wb_add_entry(&wb_data), ret, done);
            wb_data.valid_cnt = 0;
        }
        CTC_WB_SYNC_END_DATA(CTC_FEATURE_SCL, SYS_WB_APPID_SCL_SUBID_DEFAULT_ENTRY);
    }

    if ((app_id == 0 || CTC_WB_SUBID(app_id) == SYS_WB_APPID_SCL_SUBID_FLEX_KEY) && DRV_FROM_AT(lchip))
    {
        CTC_WB_INIT_DATA_T((&wb_data), sys_wb_scl_flex_key_t, CTC_FEATURE_SCL, SYS_WB_APPID_SCL_SUBID_FLEX_KEY);
        user_data.data0 = (void*)&wb_data;
        user_data.data1 = NULL;
        user_data.value0 = lchip;
        user_data.value1 = 0;
        CTC_ERROR_GOTO(ctc_vector_traverse(p_usw_scl_master[lchip]->flex_key_vec, _sys_usw_scl_wb_sync_flex_key_func, (void*)(&user_data)), ret, done);
        if (wb_data.valid_cnt > 0)
        {
            CTC_ERROR_GOTO(ctc_wb_add_entry(&wb_data), ret, done);
            wb_data.valid_cnt = 0;
        }
        CTC_WB_SYNC_END_DATA(CTC_FEATURE_SCL, SYS_WB_APPID_SCL_SUBID_FLEX_KEY);
    }

done:
    SYS_SCL_UNLOCK(lchip);
    CTC_WB_FREE_BUFFER(wb_data.buffer);
    mem_free(block);
    return ret;
}

int32
sys_usw_scl_wb_restore(uint8 lchip)
{
    int32  ret       = CTC_E_NONE;
    uint32 cmd = 0;
    uint32 value = 0;
    uint32 entry_cnt = 0;
    uint16 def_entry_index = 0;
    uint16 size = 0;
    ctc_wb_query_t wb_query;
    sys_wb_scl_master_t wb_scl_master;
    sys_wb_scl_flex_key_t wb_scl_flex_key;
    sys_scl_flexed_key_t* p_scl_flexed_key = NULL;
    sys_wb_scl_group_t wb_scl_group;
    sys_scl_sw_group_t* p_scl_group = NULL;
    sys_scl_sw_entry_t* p_scl_entry = NULL;
    sys_scl_sw_block_t* pb = NULL;
    sys_wb_scl_igs_hash_entry_t wb_scl_igs_has_entry;
    sys_wb_scl_igs_tcam_entry_t wb_scl_igs_tcam_entry;
    sys_wb_scl_egs_entry_t wb_scl_egs_entry;

    uint8 loop = 0;


    CTC_WB_ALLOC_BUFFER(&wb_query.buffer);
    if (DRV_FLD_IS_EXISIT(UserIdHashLookupCtl_t, UserIdHashLookupCtl_userIdDefaultEntryBase_f))
    {
        cmd   = DRV_IOR(UserIdHashLookupCtl_t, UserIdHashLookupCtl_userIdDefaultEntryBase_f);
        DRV_FIELD_IOCTL(lchip, 0, DRV_CMD_BMP_EN(cmd, MCHIP_FEATURE_PP_EN(lchip,CTC_FEATURE_SCL)), &value);
        p_usw_scl_master[lchip]->igs_default_base[0] = value;
    }
    else
    {
        cmd   = DRV_IOR(UserIdHashLookupCtl_t, UserIdHashLookupCtl_userIdHashLookup0DefaultEntryBase_f);
        DRV_FIELD_IOCTL(lchip, 0, DRV_CMD_BMP_EN(cmd, MCHIP_FEATURE_PP_EN(lchip,CTC_FEATURE_SCL)), &value);
        p_usw_scl_master[lchip]->igs_default_base[0] = value;
        cmd   = DRV_IOR(UserIdHashLookupCtl_t, UserIdHashLookupCtl_userIdHashLookup1DefaultEntryBase_f);
        DRV_FIELD_IOCTL(lchip, 0, DRV_CMD_BMP_EN(cmd, MCHIP_FEATURE_PP_EN(lchip,CTC_FEATURE_SCL)), &value);
        p_usw_scl_master[lchip]->igs_default_base[1] = value;
    }

    cmd   = DRV_IOR(UserIdHashLookupCtl_t, DRV_FROM_TMM(lchip)? UserIdHashLookupCtl_tunnelId0DefaultEntryBase_f: UserIdHashLookupCtl_tunnelIdDefaultEntryBase_f);
    DRV_FIELD_IOCTL(lchip, 0, DRV_CMD_BMP_EN(cmd, MCHIP_FEATURE_PP_EN(lchip,CTC_FEATURE_SCL)), &value);
    p_usw_scl_master[lchip]->tunnel_default_base[0] = value;
    if (DRV_FROM_TMM(lchip))
    {
        cmd   = DRV_IOR(UserIdHashLookupCtl_t, UserIdHashLookupCtl_tunnelId1DefaultEntryBase_f);
        DRV_FIELD_IOCTL(lchip, 0, DRV_CMD_BMP_EN(cmd, MCHIP_FEATURE_PP_EN(lchip,CTC_FEATURE_SCL)), &value);
        p_usw_scl_master[lchip]->tunnel_default_base[1] = value;
    }

    /* restore scl master */
    CTC_WB_INIT_QUERY_T((&wb_query), sys_wb_scl_master_t, CTC_FEATURE_SCL, SYS_WB_APPID_SCL_SUBID_MASTER);
    /* set default value for new added fields, the default vlaue may not be zeros */
    sal_memset(&wb_scl_master, 0, sizeof(sys_wb_scl_master_t));

    for(loop=0; loop < MCHIP_CAP(SYS_CAP_SCL_TCAM_NUM); loop++)
    {
        p_usw_scl_master[lchip]->fpa_block[loop].fpab.entry_count = 0;
        p_usw_scl_master[lchip]->fpa_block[loop].fpab.free_count = 0;
    }
    CTC_WB_QUERY_ENTRY_BEGIN((&wb_query));
        sal_memcpy((uint8*)&wb_scl_master, (uint8*)(wb_query.buffer) + entry_cnt * (wb_query.key_len + wb_query.data_len), wb_query.key_len + wb_query.data_len);
        if (CTC_WB_VERSION_CHECK(SYS_WB_VERSION_SCL, wb_scl_master.version))
        {
            ret = CTC_E_VERSION_MISMATCH;
            goto done;
        }

        pb = &p_usw_scl_master[wb_scl_master.lchip]->fpa_block[wb_scl_master.block_id];
        pb->fpab.start_offset[wb_scl_master.key_size_type] = wb_scl_master.start_offset;
        pb->fpab.sub_entry_count[wb_scl_master.key_size_type] = wb_scl_master.sub_entry_count;
        pb->fpab.sub_free_count[wb_scl_master.key_size_type] = wb_scl_master.sub_free_count;
        pb->fpab.entry_count += wb_scl_master.sub_entry_count*SYS_SCL_GET_STEP(wb_scl_master.key_size_type);
        pb->fpab.free_count += wb_scl_master.sub_free_count*SYS_SCL_GET_STEP(wb_scl_master.key_size_type);

        entry_cnt++;
    CTC_WB_QUERY_ENTRY_END((&wb_query));

    if(DRV_FROM_AT(lchip) && lchip == SYS_PP_BASE(lchip))
    {
        /* restore flex key */
        CTC_WB_INIT_QUERY_T((&wb_query), sys_wb_scl_flex_key_t, CTC_FEATURE_SCL, SYS_WB_APPID_SCL_SUBID_FLEX_KEY);

        /* set default value for new added fields, the default value may not be zeros */
        sal_memset(&wb_scl_flex_key, 0, sizeof(sys_wb_scl_flex_key_t));
        CTC_WB_QUERY_ENTRY_BEGIN((&wb_query));
            sal_memcpy((uint8*)&wb_scl_flex_key, (uint8*)(wb_query.buffer) + entry_cnt * (wb_query.key_len + wb_query.data_len), wb_query.key_len + wb_query.data_len);
            entry_cnt++;
            p_scl_flexed_key = mem_malloc(MEM_SCL_MODULE, sizeof(sys_scl_flexed_key_t));
            if (NULL == p_scl_flexed_key)
            {
                ret = CTC_E_NO_MEMORY;
                goto done;
            }
            sal_memset(p_scl_flexed_key, 0, sizeof(sys_scl_flexed_key_t));
            CTC_ERROR_GOTO(_sys_usw_scl_wb_mapping_flex_key(lchip, &wb_scl_flex_key, p_scl_flexed_key, 0), ret, done);
            if (FALSE == ctc_vector_add(p_usw_scl_master[lchip]->flex_key_vec, wb_scl_flex_key.key_type, p_scl_flexed_key))
            {
                ret = CTC_E_NO_MEMORY;
                goto done;
            }

        CTC_WB_QUERY_ENTRY_END((&wb_query));
    }
    /* restore scl group */
    CTC_WB_INIT_QUERY_T((&wb_query), sys_wb_scl_group_t, CTC_FEATURE_SCL, SYS_WB_APPID_SCL_SUBID_GROUP);

    /* set default value for new added fields, the default value may not be zeros */
    sal_memset(&wb_scl_group, 0, sizeof(sys_wb_scl_group_t));
    CTC_WB_QUERY_ENTRY_BEGIN((&wb_query));
        sal_memcpy((uint8*)&wb_scl_group, (uint8*)(wb_query.buffer) + entry_cnt * (wb_query.key_len + wb_query.data_len), wb_query.key_len + wb_query.data_len);
        entry_cnt++;
        p_scl_group = mem_malloc(MEM_SCL_MODULE, sizeof(sys_scl_sw_group_t));
        if (NULL == p_scl_group)
        {
            ret = CTC_E_NO_MEMORY;
            goto done;
        }
        sal_memset(p_scl_group, 0, sizeof(sys_scl_sw_group_t));
        CTC_ERROR_GOTO(_sys_usw_scl_wb_mapping_group(lchip,&wb_scl_group, p_scl_group, 0), ret, done);

        if (NULL == ctc_hash_insert(p_usw_scl_master[lchip]->group, (void*)p_scl_group))
        {
            ret = CTC_E_NO_MEMORY;
            goto done;
        }

    CTC_WB_QUERY_ENTRY_END((&wb_query));


  /* restore scl igs hash entry */
    CTC_WB_INIT_QUERY_T((&wb_query), sys_wb_scl_igs_hash_entry_t, CTC_FEATURE_SCL, SYS_WB_APPID_SCL_SUBID_IGS_HASH_ENTRY);

    /* set default value for new added fields, the default value may not be zeros */
    sal_memset(&wb_scl_igs_has_entry, 0, sizeof(sys_wb_scl_igs_hash_entry_t));
    CTC_WB_QUERY_ENTRY_BEGIN((&wb_query));
        sal_memcpy((uint8*)&wb_scl_igs_has_entry, (uint8*)(wb_query.buffer) + entry_cnt * (wb_query.key_len + wb_query.data_len), wb_query.key_len + wb_query.data_len);
        entry_cnt++;
        size = sizeof(sys_scl_sw_entry_t);
        p_scl_entry = mem_malloc(MEM_SCL_MODULE, size);
        if (NULL == p_scl_entry)
        {
            ret = CTC_E_NO_MEMORY;
            goto done;
        }
        sal_memset(p_scl_entry, 0, size);
        CTC_ERROR_GOTO(_sys_usw_scl_wb_mapping_igs_hash_entry(lchip, &wb_scl_igs_has_entry, p_scl_entry, 0, 0), ret, done);
        if(p_scl_entry->uninstall)
        {
            _sys_usw_scl_free_entry_node_data((void*)p_scl_entry, (void*)&lchip);
            continue;
        }
        if (NULL == ctc_hash_insert(p_usw_scl_master[lchip]->entry, (void*)p_scl_entry))
        {
            ret = CTC_E_NO_MEMORY;
            goto done;
        }

    CTC_WB_QUERY_ENTRY_END((&wb_query));

      /* restore scl igs tcam entry */
    CTC_WB_INIT_QUERY_T((&wb_query), sys_wb_scl_igs_tcam_entry_t, CTC_FEATURE_SCL, SYS_WB_APPID_SCL_SUBID_IGS_TCAM_ENTRY);

    /* set default value for new added fields, the default value may not be zeros */
    sal_memset(&wb_scl_igs_tcam_entry, 0, sizeof(sys_wb_scl_igs_tcam_entry_t));
    CTC_WB_QUERY_ENTRY_BEGIN((&wb_query));
        sal_memcpy((uint8*)&wb_scl_igs_tcam_entry, (uint8*)(wb_query.buffer) + entry_cnt * (wb_query.key_len + wb_query.data_len), wb_query.key_len + wb_query.data_len);
        entry_cnt++;
        size = sizeof(sys_scl_sw_entry_tcam_t);
        p_scl_entry = mem_malloc(MEM_SCL_MODULE, size);
        if (NULL == p_scl_entry)
        {
            ret = CTC_E_NO_MEMORY;
            goto done;
        }
        sal_memset(p_scl_entry, 0, size);
        CTC_ERROR_GOTO(_sys_usw_scl_wb_mapping_igs_tcam_entry(lchip, &wb_scl_igs_tcam_entry, (sys_scl_sw_entry_tcam_t*)p_scl_entry, 0, 0), ret, done);
        if(p_scl_entry->uninstall)
        {
            _sys_usw_scl_free_entry_node_data((void*)p_scl_entry, (void*)&lchip);
            continue;
        }
        if (NULL == ctc_hash_insert(p_usw_scl_master[lchip]->entry, (void*)p_scl_entry))
        {
            ret = CTC_E_NO_MEMORY;
            goto done;
        }

    CTC_WB_QUERY_ENTRY_END((&wb_query));

  /* restore scl egs entry */
    CTC_WB_INIT_QUERY_T((&wb_query), sys_wb_scl_egs_entry_t, CTC_FEATURE_SCL, SYS_WB_APPID_SCL_SUBID_EGS_HASH_ENTRY);

    /* set default value for new added fields, the default value may not be zeros */
    sal_memset(&wb_scl_egs_entry, 0, sizeof(sys_wb_scl_egs_entry_t));
    CTC_WB_QUERY_ENTRY_BEGIN((&wb_query));
        sal_memcpy((uint8*)&wb_scl_egs_entry, (uint8*)(wb_query.buffer) + entry_cnt * (wb_query.key_len + wb_query.data_len), wb_query.key_len + wb_query.data_len);
        entry_cnt++;
        size = sizeof(sys_scl_sw_entry_t);
        p_scl_entry = mem_malloc(MEM_SCL_MODULE, size);
        if (NULL == p_scl_entry)
        {
            ret = CTC_E_NO_MEMORY;
            goto done;
        }
        sal_memset(p_scl_entry, 0, size);
        CTC_ERROR_GOTO(_sys_usw_scl_wb_mapping_egs_entry(lchip, &wb_scl_egs_entry, p_scl_entry, 0, 0), ret, done);
        if(p_scl_entry->uninstall)
        {
            _sys_usw_scl_free_entry_node_data((void*)p_scl_entry, (void*)&lchip);
            continue;
        }
        if (NULL == ctc_hash_insert(p_usw_scl_master[lchip]->entry, (void*)p_scl_entry))
        {
            ret = CTC_E_NO_MEMORY;
            goto done;
        }

    CTC_WB_QUERY_ENTRY_END((&wb_query));
#if 0
    /* restore scl entry */
    CTC_WB_INIT_QUERY_T((&wb_query), sys_wb_scl_entry_t, CTC_FEATURE_SCL, SYS_WB_APPID_SCL_SUBID_ENTRY);

    /* set default value for new added fields, the default value may not be zeros */
    sal_memset(&wb_scl_entry, 0, sizeof(sys_wb_scl_entry_t));
    CTC_WB_QUERY_ENTRY_BEGIN((&wb_query));
        sal_memcpy((uint8*)&wb_scl_entry, (uint8*)(wb_query.buffer) + entry_cnt * (wb_query.key_len + wb_query.data_len), wb_query.key_len + wb_query.data_len);
        entry_cnt++;
        if (wb_scl_entry.is_xkey)
        {
            p_scl_flex_key = ctc_vector_get(p_usw_scl_master[lchip]->flex_key_vec, wb_scl_entry.key_type);
            if(!p_scl_flex_key)
            {
                CTC_ERROR_RETURN(CTC_E_NOT_EXIST);
            }
            size = SCL_ENTRY_IS_TCAM(p_scl_flex_key->origin_key_type)? sizeof(sys_scl_sw_entry_tcam_t): sizeof(sys_scl_sw_entry_t);
        }
        else
        {
            size = SCL_ENTRY_IS_TCAM(wb_scl_entry.key_type)? sizeof(sys_scl_sw_entry_tcam_t): sizeof(sys_scl_sw_entry_t);
        }

        p_scl_entry = mem_malloc(MEM_SCL_MODULE, size);
        if (NULL == p_scl_entry)
        {
            ret = CTC_E_NO_MEMORY;
            goto done;
        }
        sal_memset(p_scl_entry, 0, size);
        CTC_ERROR_GOTO(_sys_usw_scl_wb_mapping_entry(lchip, &wb_scl_entry, p_scl_entry, 0, 0), ret, done);
        if(p_scl_entry->uninstall)
        {
            _sys_usw_scl_free_entry_node_data((void*)p_scl_entry, (void*)&lchip);
            continue;
        }
        if (NULL == ctc_hash_insert(p_usw_scl_master[lchip]->entry, (void*)p_scl_entry))
        {
            ret = CTC_E_NO_MEMORY;
            goto done;
        }

    CTC_WB_QUERY_ENTRY_END((&wb_query));
#endif
    CTC_WB_INIT_QUERY_T((&wb_query), sys_wb_scl_igs_hash_entry_t, CTC_FEATURE_SCL, SYS_WB_APPID_SCL_SUBID_DEFAULT_ENTRY);
    sal_memset(&wb_scl_igs_has_entry, 0, sizeof(sys_wb_scl_igs_hash_entry_t));
    CTC_WB_QUERY_ENTRY_BEGIN((&wb_query));
        sal_memcpy((uint8*)&wb_scl_igs_has_entry, (uint8*)(wb_query.buffer) + entry_cnt * (wb_query.key_len + wb_query.data_len), wb_query.key_len + wb_query.data_len);
        entry_cnt++;
        p_scl_entry = mem_malloc(MEM_SCL_MODULE, sizeof(sys_scl_sw_entry_t));
        if (NULL == p_scl_entry)
        {
            ret = CTC_E_NO_MEMORY;
            goto done;
        }
        sal_memset(p_scl_entry, 0, sizeof(sys_scl_sw_entry_t));
        CTC_ERROR_GOTO(_sys_usw_scl_wb_mapping_igs_hash_entry(lchip, &wb_scl_igs_has_entry, p_scl_entry, 0, 1), ret, done);
        def_entry_index = SYS_SCL_ENCODE_DEF_ENTRY_INDEX((p_scl_entry->entry_id>>24), ((p_scl_entry->entry_id>>8)&0xFFFF), (p_scl_entry->entry_id&0xFF));
        ctc_vector_add(p_usw_scl_master[lchip]->default_entry, def_entry_index, (void*)p_scl_entry);
    CTC_WB_QUERY_ENTRY_END((&wb_query));

done:
  CTC_WB_FREE_BUFFER(wb_query.buffer);

    return ret;
}

#define __scl_internal_function__

int32
_sys_usw_scl_offset_map_chunk(ctc_xdata_field_t* field, uint8 dir, uint32* chunk_bmp_o)
{
    uint8 start = field->offset;
    uint32 chunk_bmp = 0;

    if(CTC_INGRESS == dir)
    {
        if(start<16)
        {
            CTC_SET_FLAG(chunk_bmp, SYS_SCL_XDATA_IGS_CHUNK3_WORD0);        /*0-16*/
        }else if(start<32)
        {
            CTC_SET_FLAG(chunk_bmp, SYS_SCL_XDATA_IGS_CHUNK4_WORD1);        /*16-32*/
        }else if(start<40)
        {
            CTC_SET_FLAG(chunk_bmp, SYS_SCL_XDATA_IGS_CHUNK2_BYTE0);      /*32-40*/
        }
        else if(start<48)
        {
            CTC_SET_FLAG(chunk_bmp, SYS_SCL_XDATA_IGS_CHUNK2_BYTE1);      /*40-48*/
        }
        else if(start<64)
        {
            CTC_SET_FLAG(chunk_bmp, SYS_SCL_XDATA_IGS_CHUNK1_NIBBLE3_0);    /*48-64*/
        }else
        {
            CTC_SET_FLAG(chunk_bmp, SYS_SCL_XDATA_IGS_CHUNK0_NIBBLE4);      /*64-68*/
        }
    }
    else
    {
        if(start < 48)
        {
           CTC_SET_FLAG(chunk_bmp, SYS_SCL_XDATA_EGS_CHUNK2_BYTE1_0);
        }
        else if(start < 64)
        {
            CTC_SET_FLAG(chunk_bmp, SYS_SCL_XDATA_EGS_CHUNK1_NIBBLE3_0);
        }
        else
        {
            return CTC_E_NOT_SUPPORT;
        }
    }
    *chunk_bmp_o |= chunk_bmp;

    return 0;
}

int32 
_sys_usw_scl_check_xdata(uint8 lchip, sys_scl_sw_entry_t* pe, ctc_scl_field_action_t* pAction, void* ds, uint8 is_add, uint32* chunk_bmp_o)
{

    uint8 loop = 0;
    uint32 chunk_bmp = 0;
    ctc_xdata_t xdata;
    ctc_xdata_field_t fields[9];
    uint32 action_bmp[CTC_B2W_SIZE(SYS_SCL_FIELD_ACTION_TYPE_MAX)];

    if(!DRV_FROM_AT(lchip))
    {
        return  CTC_E_NOT_SUPPORT;
    }

    sal_memset(&xdata, 0, sizeof(ctc_xdata_t));
    sal_memset(&fields, 0, sizeof(fields));

    sal_memcpy(action_bmp, pe->action_bmp, sizeof(action_bmp));

    if(pAction)
    {
      CTC_BMP_SET(action_bmp, pAction->type); 
    }


    if(is_add && pAction && CTC_SCL_FIELD_ACTION_TYPE_XDATA == pAction->type) 
    {
         xdata.prof_id = ((ctc_xdata_t *)pAction->ext_data)->prof_id; 
    }
    else
    {
        if(SYS_SCL_ACTION_TUNNEL == pe->action_type)
        {
            xdata.prof_id = GetDsTunnelId(V, xAdIndex_f, ds);
            if(!xdata.prof_id && !GetDsTunnelId(V, xAdEn_f, ds))
            {
                return CTC_E_NOT_EXIST;
            }
        }
        else if(CTC_INGRESS == pe->direction)
        {
            xdata.prof_id = GetDsUserId(V, xAdIndex_f, ds);
            if(!xdata.prof_id && !GetDsUserId(V, xAdEn_f, ds))
            {
                return CTC_E_NOT_EXIST;
            }
        }
        else
        {
             xdata.prof_id = GetDsVlanXlate(V, cVlanIdAction_f, ds);
             if(!xdata.prof_id && !GetDsVlanXlate(V, cCfiAction_f, ds))
             {
                    return CTC_E_NOT_EXIST;
             }
        }
    }

    xdata.fields = fields;
    xdata.type = (SYS_SCL_ACTION_TUNNEL == pe->action_type)? CTC_XDATA_PROF_TYPE_DSTUNNEL : ((CTC_INGRESS == pe->direction) ? CTC_XDATA_PROF_TYPE_DSSCL:CTC_XDATA_PROF_TYPE_EGS_DSSCL);
    CTC_ERROR_RETURN(MCHIP_XDATA(lchip)->prof_get_info(lchip, &xdata, FALSE));

    /*get chunk bmp*/
    do
    {
        CTC_ERROR_RETURN(_sys_usw_scl_offset_map_chunk(xdata.fields+loop, pe->direction, &chunk_bmp));
    }while(++loop<xdata.num);

    if(is_add && SYS_SCL_ACTION_TUNNEL == pe->action_type )
    {
         if(CTC_BMP_ISSET(action_bmp, CTC_SCL_FIELD_ACTION_TYPE_QOS_MAP) || CTC_BMP_ISSET(action_bmp, SYS_SCL_FIELD_ACTION_TYPE_QOS_USE_OUTER_INFO)||
               CTC_BMP_ISSET(action_bmp, CTC_SCL_FIELD_ACTION_TYPE_STATS) || CTC_BMP_ISSET(action_bmp, CTC_SCL_FIELD_ACTION_TYPE_POLICER_ID) ||
               CTC_BMP_ISSET(action_bmp, SYS_SCL_FIELD_ACTION_TYPE_IP_TUNNEL_DECAP)|| CTC_BMP_ISSET(action_bmp, CTC_SCL_FIELD_ACTION_TYPE_METADATA) || 
               CTC_BMP_ISSET(action_bmp, CTC_SCL_FIELD_ACTION_TYPE_L3IF_PROPERTY)|| CTC_BMP_ISSET(action_bmp, SYS_SCL_FIELD_ACTION_TYPE_TRILL))
            {
                CTC_ERROR_RETURN(CTC_E_PARAM_CONFLICT);
            }
    }
    else if(is_add && CTC_INGRESS == pe->direction)
    {
          if((CTC_FLAG_ISSET(chunk_bmp,SYS_SCL_XDATA_IGS_CHUNK0_NIBBLE4) && CTC_BMP_ISSET(action_bmp, CTC_SCL_FIELD_ACTION_TYPE_L3IF_PROPERTY)) ||
            (CTC_FLAG_ISSET(chunk_bmp,SYS_SCL_XDATA_IGS_CHUNK1_NIBBLE3_0) && (CTC_BMP_ISSET(action_bmp, SYS_SCL_FIELD_ACTION_TYPE_SRV6) ||
                                                                             (CTC_BMP_ISSET(action_bmp,CTC_SCL_FIELD_ACTION_TYPE_METADATA) && 
                                                                             (CTC_BMP_ISSET(action_bmp,CTC_SCL_FIELD_ACTION_TYPE_SRC_CID)|| CTC_BMP_ISSET(action_bmp, CTC_SCL_FIELD_ACTION_TYPE_DST_CID)))))||                                                            
            ((CTC_FLAG_ISSET(chunk_bmp,SYS_SCL_XDATA_IGS_CHUNK1_NIBBLE3_0) && (CTC_FLAG_ISSET(chunk_bmp,SYS_SCL_XDATA_IGS_CHUNK2_BYTE0) || CTC_FLAG_ISSET(chunk_bmp,SYS_SCL_XDATA_IGS_CHUNK2_BYTE1)))&&
                                                                              (CTC_BMP_ISSET(action_bmp,CTC_SCL_FIELD_ACTION_TYPE_METADATA)||
                                                                              (CTC_BMP_ISSET(action_bmp,CTC_SCL_FIELD_ACTION_TYPE_SRC_CID)|| CTC_BMP_ISSET(action_bmp, CTC_SCL_FIELD_ACTION_TYPE_DST_CID))))||
            ((CTC_FLAG_ISSET(chunk_bmp,SYS_SCL_XDATA_IGS_CHUNK2_BYTE0) || CTC_FLAG_ISSET(chunk_bmp,SYS_SCL_XDATA_IGS_CHUNK2_BYTE1))&& (CTC_BMP_ISSET(action_bmp,CTC_SCL_FIELD_ACTION_TYPE_SRC_CID) ||
                                                                          CTC_BMP_ISSET(action_bmp, CTC_SCL_FIELD_ACTION_TYPE_DST_CID) ||
                                                                          CTC_BMP_ISSET(action_bmp,SYS_SCL_FIELD_ACTION_TYPE_SRV6)))||
            (CTC_FLAG_ISSET(chunk_bmp,SYS_SCL_XDATA_IGS_CHUNK3_WORD0) && (CTC_BMP_ISSET(action_bmp,CTC_SCL_FIELD_ACTION_TYPE_POLICER_ID) ||
                                                                          CTC_BMP_ISSET(action_bmp, CTC_SCL_FIELD_ACTION_TYPE_COS_HBWP_POLICER))))
        {
            return CTC_E_PARAM_CONFLICT;
        }
    }
    else if(is_add)
    {
        if(CTC_FLAG_ISSET(chunk_bmp, SYS_SCL_XDATA_EGS_CHUNK1_NIBBLE3_0) && (CTC_BMP_ISSET(action_bmp, CTC_SCL_FIELD_ACTION_TYPE_ESLB) ||
                                                                             CTC_BMP_ISSET(action_bmp, CTC_SCL_FIELD_ACTION_TYPE_VLAN_EDIT)))
        {
            return CTC_E_PARAM_CONFLICT;
        }
        if(CTC_FLAG_ISSET(chunk_bmp,SYS_SCL_XDATA_EGS_CHUNK2_BYTE1_0) && (CTC_BMP_ISSET(action_bmp, CTC_SCL_FIELD_ACTION_TYPE_POLICER_ID) ||
                                                                          CTC_BMP_ISSET(action_bmp, CTC_SCL_FIELD_ACTION_TYPE_STATS)))
        {
            return CTC_E_PARAM_CONFLICT;
        }
    }
    *chunk_bmp_o |= chunk_bmp;
    return CTC_E_NONE;
}

int32
sys_usw_scl_buffer_malloc(uint8 lchip, sys_scl_sw_entry_t* pe, uint8 is_malloc)
{
    sys_scl_sw_temp_entry_t* new_buffer = NULL;
    void* p_ad = NULL;

    /* free buffer, must check ad exist, */
    if (!is_malloc)  /*free*/
    {
        if (!pe->u.temp_entry)
        {
            return CTC_E_NONE;
        }
        if (pe->is_buffer)   /*buffer*/
        {
            p_ad = pe->u.temp_entry->p_ad?pe->u.temp_entry->p_ad: p_ad;
            mem_free(pe->u.temp_entry);
            pe->u.ad = p_ad;
            pe->is_buffer = 0;
        }
        return CTC_E_NONE;
    }

    /*malloc buffer */
    if (!pe->is_buffer)   /*buffer*/
    {
        p_ad = pe->u.ad;
        MALLOC_ZERO(MEM_SCL_MODULE, new_buffer, sizeof(sys_scl_sw_temp_entry_t));
        if (!new_buffer)
        {
            return CTC_E_NO_MEMORY;
        }
        pe->u.temp_entry = new_buffer;
        pe->u.temp_entry->p_ad = p_ad;
        pe->is_buffer = 1;
    }

    return CTC_E_NONE;
}

int32
_sys_usw_scl_set_key_mask(uint8 lchip, sys_scl_sw_entry_t* pe)
{
#if 0
    uint32 key_id = 0, act_id = 0;
    uint32 temp_mask[295/32+1] = {0};

    if (pe->key_bmp)
    {
        sal_memset(temp_mask, 0xFF, sizeof(temp_mask));
    }

    if (DRV_FROM_TMM(lchip) && pe->resolve_conflict)
    {
        _sys_usw_scl_get_table_id(lchip, pe->group->priority, pe, &key_id, &act_id);
        if ((key_id == DsSclHash0ConflictTcamSize0_t) || (key_id == DsSclHash1ConflictTcamSize0_t))
        {
            SetDsSclHash0ConflictTcamSize0(A, data_f, pe->temp_entry->mask, temp_mask);
            SetDsSclHash0ConflictTcamSize0(V, hashType_f, pe->temp_entry->mask, 0x3F);
        }
        else if ((key_id == DsSclHash0ConflictTcamSize1_t) || (key_id == DsSclHash1ConflictTcamSize1_t))
        {
            SetDsSclHash0ConflictTcamSize1(A, data_f, pe->temp_entry->mask, temp_mask);
            SetDsSclHash0ConflictTcamSize1(V, hashType0_f, pe->temp_entry->mask, 0x3F);
            SetDsSclHash0ConflictTcamSize1(V, hashType1_f, pe->temp_entry->mask, 0x3F);
        }
        else if ((key_id == DsSclHash0ConflictTcamSize2_t) || (key_id == DsSclHash1ConflictTcamSize2_t))
        {
            SetDsSclHash0ConflictTcamSize2(A, data_f, pe->temp_entry->mask, temp_mask);
            SetDsSclHash0ConflictTcamSize2(V, hashType0_f, pe->temp_entry->mask, 0x3F);
            SetDsSclHash0ConflictTcamSize2(V, hashType1_f, pe->temp_entry->mask, 0x3F);
            SetDsSclHash0ConflictTcamSize2(V, hashType2_f, pe->temp_entry->mask, 0x3F);
            SetDsSclHash0ConflictTcamSize2(V, hashType3_f, pe->temp_entry->mask, 0x3F);
        }
    }
#endif
    return CTC_E_NONE;
}

STATIC int32
_sys_usw_scl_build_vlan_edit(uint8 lchip, void* p_ds_edit, sys_scl_sw_vlan_edit_t* p_vlan_edit)
{
    uint8 op = 0;
    uint8 mo = 0;
    uint8 st = 0;

    sys_usw_scl_vlan_tag_op_translate(lchip, p_vlan_edit->stag_op, &op, &mo);
    SetDsVlanActionProfile(V, sTagAction_f, p_ds_edit, op);
    SetDsVlanActionProfile(V, stagModifyMode_f, p_ds_edit, mo);
    sys_usw_scl_vlan_tag_op_translate(lchip, p_vlan_edit->ctag_op, &op, &mo);
    SetDsVlanActionProfile(V, cTagAction_f, p_ds_edit, op);
    SetDsVlanActionProfile(V, ctagModifyMode_f, p_ds_edit, mo);

    SetDsVlanActionProfile(V, sVlanIdAction_f, p_ds_edit, p_vlan_edit->svid_sl);
    SetDsVlanActionProfile(V, sCosAction_f, p_ds_edit, p_vlan_edit->scos_sl);
    SetDsVlanActionProfile(V, sCfiAction_f, p_ds_edit, p_vlan_edit->scfi_sl);

    SetDsVlanActionProfile(V, cVlanIdAction_f, p_ds_edit, p_vlan_edit->cvid_sl);
    SetDsVlanActionProfile(V, cCosAction_f, p_ds_edit, p_vlan_edit->ccos_sl);
    SetDsVlanActionProfile(V, cCfiAction_f, p_ds_edit, p_vlan_edit->ccfi_sl);

    SetDsVlanActionProfile(V, svlanTpidIndexEn_f, p_ds_edit, 1);
    SetDsVlanActionProfile(V, svlanTpidIndex_f, p_ds_edit, p_vlan_edit->tpid_index);

    switch (p_vlan_edit->vlan_domain)
    {
        case CTC_SCL_VLAN_DOMAIN_SVLAN:
            st = 2;
            break;
        case CTC_SCL_VLAN_DOMAIN_CVLAN:
            st = 1;
            break;
        case CTC_SCL_VLAN_DOMAIN_UNCHANGE:
            st = 0;
            break;
        default:
            break;
    }
    SetDsVlanActionProfile(V, outerVlanStatus_f, p_ds_edit, st);
/*
   ctagAddMode_f
   svlanTpidIndexEn_f
   svlanTpidIndex_f
   ds_vlan_action_profile_t
 */
    return CTC_E_NONE;
}

STATIC int32
_sys_usw_scl_vlan_edit_static_add(uint8 lchip, sys_scl_sw_vlan_edit_t* p_vlan_edit, uint16* p_prof_idx)
{
    uint32 cmd = 0;
    int32  ret = CTC_E_NONE ;
    sys_scl_sp_vlan_edit_t *p_sp_vlan_edit = NULL;
    sys_scl_sp_vlan_edit_t sp_vlan_edit;
    sys_scl_sp_vlan_edit_t out_vlan_edit;

    sal_memset(&sp_vlan_edit, 0, sizeof(sp_vlan_edit));
    sal_memset(&out_vlan_edit, 0, sizeof(out_vlan_edit));
    p_sp_vlan_edit = &sp_vlan_edit;

    p_sp_vlan_edit->profile_id = *p_prof_idx;

    _sys_usw_scl_build_vlan_edit(lchip, &p_sp_vlan_edit->action_profile, p_vlan_edit);
    if (ctc_spool_static_add(p_usw_scl_master[lchip]->vlan_edit_spool, p_sp_vlan_edit) < 0)
    {
        CTC_ERROR_GOTO(CTC_E_NO_MEMORY, ret, error_proc);
    }
    cmd = DRV_IOW(DsVlanActionProfile_t, DRV_ENTRY_FLAG);
    if ((DRV_IOCTL(lchip, p_sp_vlan_edit->profile_id, DRV_CMD_BMP_EN(cmd, MCHIP_FEATURE_PP_EN(lchip,CTC_FEATURE_SCL)), &p_sp_vlan_edit->action_profile)) < 0 )
    {
        CTC_ERROR_GOTO(CTC_E_HW_FAIL, ret, error_proc);
    }

    *p_prof_idx = *p_prof_idx + 1;

    return CTC_E_NONE;
error_proc:
    ctc_spool_remove(p_usw_scl_master[lchip]->vlan_edit_spool, p_sp_vlan_edit, &out_vlan_edit);
    return ret;
}

STATIC int32
_sys_usw_scl_stag_edit_template_build(uint8 lchip, sys_scl_sw_vlan_edit_t* p_vlan_edit, uint16* p_prof_idx)
{
    uint8 stag_op = 0;


    for (stag_op = CTC_VLAN_TAG_OP_NONE; stag_op < CTC_VLAN_TAG_OP_MAX; stag_op++)
    {
        p_vlan_edit->stag_op = stag_op;

        switch (stag_op)
        {
        case CTC_VLAN_TAG_OP_REP:         /* template has no replace */
        case CTC_VLAN_TAG_OP_VALID:       /* template has no valid */
            break;
        case CTC_VLAN_TAG_OP_REP_OR_ADD:
        case CTC_VLAN_TAG_OP_ADD:
        {
            p_vlan_edit->svid_sl = CTC_VLAN_TAG_SL_NEW;
            p_vlan_edit->scos_sl = CTC_VLAN_TAG_SL_NEW;
            CTC_ERROR_RETURN(_sys_usw_scl_vlan_edit_static_add(lchip, p_vlan_edit, p_prof_idx));

            p_vlan_edit->svid_sl = CTC_VLAN_TAG_SL_NEW;
            p_vlan_edit->scos_sl = CTC_VLAN_TAG_SL_AS_PARSE;
            CTC_ERROR_RETURN(_sys_usw_scl_vlan_edit_static_add(lchip, p_vlan_edit, p_prof_idx));

            p_vlan_edit->svid_sl = CTC_VLAN_TAG_SL_AS_PARSE;
            p_vlan_edit->scos_sl = CTC_VLAN_TAG_SL_AS_PARSE;
            CTC_ERROR_RETURN(_sys_usw_scl_vlan_edit_static_add(lchip, p_vlan_edit, p_prof_idx));

            p_vlan_edit->svid_sl = CTC_VLAN_TAG_SL_AS_PARSE;
            p_vlan_edit->scos_sl = CTC_VLAN_TAG_SL_NEW;
            CTC_ERROR_RETURN(_sys_usw_scl_vlan_edit_static_add(lchip, p_vlan_edit, p_prof_idx));
        }
        break;
        case CTC_VLAN_TAG_OP_NONE:
        case CTC_VLAN_TAG_OP_DEL:
            p_vlan_edit->svid_sl = CTC_VLAN_TAG_SL_AS_PARSE;
            p_vlan_edit->scos_sl = CTC_VLAN_TAG_SL_AS_PARSE;
            CTC_ERROR_RETURN(_sys_usw_scl_vlan_edit_static_add(lchip, p_vlan_edit, p_prof_idx));
            break;
        }
    }

    return CTC_E_NONE;
}


STATIC int32
_sys_usw_scl_rsv_vlan_edit(uint8 lchip)
{
    uint16                 prof_idx = 1;
    uint8                  ctag_op  = 0;

    sys_scl_sw_vlan_edit_t vlan_edit;
    sal_memset(&vlan_edit, 0, sizeof(vlan_edit));

    vlan_edit.vlan_domain = CTC_SCL_VLAN_DOMAIN_UNCHANGE;
    for (ctag_op = CTC_VLAN_TAG_OP_NONE; ctag_op < CTC_VLAN_TAG_OP_MAX; ctag_op++)
    {
        vlan_edit.ctag_op = ctag_op;

        switch (ctag_op)
        {
            case CTC_VLAN_TAG_OP_ADD :           /* template has no append ctag */
            case CTC_VLAN_TAG_OP_REP :           /* template has no replace */
            case CTC_VLAN_TAG_OP_VALID :         /* template has no valid */
                break;
            case CTC_VLAN_TAG_OP_REP_OR_ADD:
                {
                    vlan_edit.cvid_sl = CTC_VLAN_TAG_SL_NEW;
                    vlan_edit.ccos_sl = CTC_VLAN_TAG_SL_NEW;
                    CTC_ERROR_RETURN(_sys_usw_scl_stag_edit_template_build(lchip, &vlan_edit, &prof_idx));

                    vlan_edit.cvid_sl = CTC_VLAN_TAG_SL_NEW;
                    vlan_edit.ccos_sl = CTC_VLAN_TAG_SL_AS_PARSE;
                    CTC_ERROR_RETURN(_sys_usw_scl_stag_edit_template_build(lchip, &vlan_edit, &prof_idx));

                    vlan_edit.cvid_sl = CTC_VLAN_TAG_SL_AS_PARSE;
                    vlan_edit.ccos_sl = CTC_VLAN_TAG_SL_AS_PARSE;
                    CTC_ERROR_RETURN(_sys_usw_scl_stag_edit_template_build(lchip, &vlan_edit, &prof_idx));

                    vlan_edit.cvid_sl = CTC_VLAN_TAG_SL_AS_PARSE;
                    vlan_edit.ccos_sl = CTC_VLAN_TAG_SL_NEW;
                    CTC_ERROR_RETURN(_sys_usw_scl_stag_edit_template_build(lchip, &vlan_edit, &prof_idx));
                }
                break;
            case CTC_VLAN_TAG_OP_NONE:
            case CTC_VLAN_TAG_OP_DEL:
                vlan_edit.cvid_sl = CTC_VLAN_TAG_SL_AS_PARSE;
                vlan_edit.ccos_sl = CTC_VLAN_TAG_SL_AS_PARSE;
                CTC_ERROR_RETURN(_sys_usw_scl_stag_edit_template_build(lchip, &vlan_edit, &prof_idx));
                break;
        }
    }

    /*for swap*/
    vlan_edit.ctag_op = CTC_VLAN_TAG_OP_REP_OR_ADD;
    vlan_edit.stag_op = CTC_VLAN_TAG_OP_REP_OR_ADD;

    vlan_edit.cvid_sl = CTC_VLAN_TAG_SL_ALTERNATIVE;
    vlan_edit.ccos_sl = CTC_VLAN_TAG_SL_ALTERNATIVE;
    vlan_edit.svid_sl = CTC_VLAN_TAG_SL_ALTERNATIVE;
    vlan_edit.scos_sl = CTC_VLAN_TAG_SL_ALTERNATIVE;
    CTC_ERROR_RETURN(_sys_usw_scl_vlan_edit_static_add(lchip, &vlan_edit, &prof_idx));

    vlan_edit.cvid_sl = CTC_VLAN_TAG_SL_ALTERNATIVE;
    vlan_edit.ccos_sl = CTC_VLAN_TAG_SL_AS_PARSE;
    vlan_edit.svid_sl = CTC_VLAN_TAG_SL_ALTERNATIVE;
    vlan_edit.scos_sl = CTC_VLAN_TAG_SL_AS_PARSE;
    CTC_ERROR_RETURN(_sys_usw_scl_vlan_edit_static_add(lchip, &vlan_edit, &prof_idx));

    vlan_edit.cvid_sl = CTC_VLAN_TAG_SL_AS_PARSE;
    vlan_edit.ccos_sl = CTC_VLAN_TAG_SL_ALTERNATIVE;
    vlan_edit.svid_sl = CTC_VLAN_TAG_SL_AS_PARSE;
    vlan_edit.scos_sl = CTC_VLAN_TAG_SL_ALTERNATIVE;
    CTC_ERROR_RETURN(_sys_usw_scl_vlan_edit_static_add(lchip, &vlan_edit, &prof_idx));

    return CTC_E_NONE;
}

STATIC int32
_sys_usw_scl_init_default_entry(uint8 lchip)
{

    uint16          lport;
    uint32          cmd      = 0;
    uint8           index    = 0;
    uint8           tunnel_def_index = 0;
    DsTunnelId_m    tunnelid;
    DsUserId_m      userid;
    DsVlanXlateDefault_m   vlanXlate;
    /* init userid default entry */

#ifdef EMULATION_ENV
    return CTC_E_NONE;
#endif

    sal_memset(&userid, 0, sizeof(DsUserId_m));
    /* ingress hash default entry */
    for (lport = 0; lport < SYS_USW_MAX_PORT_NUM_PER_CHIP; lport++)
    {
        cmd = DRV_IOW(DsUserId_t, DRV_ENTRY_FLAG);
        CTC_ERROR_RETURN(DRV_IOCTL(lchip, p_usw_scl_master[lchip]->igs_default_base[0] + 2*lport, DRV_CMD_BMP_EN(cmd,
                          MCHIP_FEATURE_PP_EN(lchip,CTC_FEATURE_SCL)), &userid));
        if (2 == MCHIP_CAP(SYS_CAP_SCL_HASH_NUM))
        {
            cmd = DRV_IOW(DsUserId1_t, DRV_ENTRY_FLAG);
            CTC_ERROR_RETURN(DRV_IOCTL(lchip, p_usw_scl_master[lchip]->igs_default_base[1] + 2*lport, DRV_CMD_BMP_EN(cmd,
                              MCHIP_FEATURE_PP_EN(lchip,CTC_FEATURE_SCL)), &userid));
        }
    }

    sal_memset(&vlanXlate, 0, sizeof(DsVlanXlateDefault_m));
    /* egress hash default entry */
    if (DRV_FROM_AT(lchip))
    {
        for (lport = 0; lport < SYS_USW_MAX_PORT_NUM_PER_CHIP; lport++)
        {

            cmd = DRV_IOW(DsVlanXlateDefault0_t, DRV_ENTRY_FLAG);
            CTC_ERROR_RETURN(DRV_IOCTL(lchip, lport, DRV_CMD_BMP_EN(cmd, MCHIP_FEATURE_PP_EN(lchip,CTC_FEATURE_SCL)), &vlanXlate));
            cmd = DRV_IOW(DsVlanXlateDefault1_t, DRV_ENTRY_FLAG);
            CTC_ERROR_RETURN(DRV_IOCTL(lchip, lport, DRV_CMD_BMP_EN(cmd, MCHIP_FEATURE_PP_EN(lchip,CTC_FEATURE_SCL)), &vlanXlate));
        }
    }
    else
    {
        for (lport = 0; lport < SYS_USW_MAX_PORT_NUM_PER_CHIP; lport++)
        {

            cmd = DRV_IOW(DsVlanXlateDefault_t, DRV_ENTRY_FLAG);
            CTC_ERROR_RETURN(DRV_IOCTL(lchip, lport, DRV_CMD_BMP_EN(cmd, MCHIP_FEATURE_PP_EN(lchip,CTC_FEATURE_SCL)), &vlanXlate));
        }
    }

    sal_memset(&tunnelid, 0, sizeof(DsTunnelId_m));
    /* init ip-tunnel default entry */
    for (index = 0; index <= (DRV_ENUM(DRV_USERIDHASHTYPE_TUNNELIPV4DA) - DRV_ENUM(DRV_USERIDHASHTYPE_TUNNELIPV4)); index++)
    {
        cmd = DRV_IOW(DsTunnelId_t, DRV_ENTRY_FLAG);
        CTC_ERROR_RETURN(DRV_IOCTL(lchip, p_usw_scl_master[lchip]->tunnel_default_base[0] + 2*index, DRV_CMD_BMP_EN(cmd,
                          MCHIP_FEATURE_PP_EN(lchip,CTC_FEATURE_SCL)), &tunnelid));
        if (2 == MCHIP_CAP(SYS_CAP_SCL_HASH_NUM))
        {
            tunnel_def_index = DRV_FROM_TMM(lchip)? 1: 0;
            cmd = DRV_IOW(DsTunnelId1_t, DRV_ENTRY_FLAG);
            CTC_ERROR_RETURN(DRV_IOCTL(lchip, p_usw_scl_master[lchip]->tunnel_default_base[tunnel_def_index] + 2*index,
                              DRV_CMD_BMP_EN(cmd, MCHIP_FEATURE_PP_EN(lchip,CTC_FEATURE_SCL)), &tunnelid));
        }
    }

    return CTC_E_NONE;
}

int32
sys_usw_scl_set_vxlan_lookup(uint8 lchip ,uint8 is_set)
{
    uint32 ad_mask[6] = {0};
    uint32 cmd = 0;
    uint32 resved = 0;
    uint32 scl_mimicry_en = 0;
    IpeUserIdMimicryCtl_m mimicryctl;

    if(!(SYS_GET_CHIP_VERSION != SYS_CHIP_SUB_VERSION_A && DRV_IS_TSINGMA(lchip)))
    {
        return CTC_E_NONE;
    }
    cmd = DRV_IOR(IpeHdrAdjReserved_t, IpeHdrAdjReserved_reserved_f);
    CTC_ERROR_RETURN(DRV_FIELD_IOCTL(lchip, 0, DRV_CMD_BMP_EN(cmd, MCHIP_FEATURE_PP_EN(lchip,CTC_FEATURE_SCL)), &resved));

    if(is_set)
    {
        cmd = DRV_IOR(IpeUserIdMimicryCtl_t, IpeUserIdMimicryCtl_sclMimicryEn_f);
        CTC_ERROR_RETURN(DRV_FIELD_IOCTL(lchip, 0, DRV_CMD_BMP_EN(cmd, MCHIP_FEATURE_PP_EN(lchip,CTC_FEATURE_SCL)), &scl_mimicry_en));
        if(scl_mimicry_en == 1 && (resved & 0x02) == 0)
        {
            return CTC_E_PARAM_CONFLICT;
        }

        sal_memset(&mimicryctl, 0, sizeof(mimicryctl));

        /*clear default entry action when use hashtype below:
        USERIDHASHTYPE_TUNNELIPV4UCVXLANMODE0,USERIDHASHTYPE_TUNNELIPV4MCVXLANMODE0,USERIDHASHTYPE_TUNNELIPV6UCVXLANMODE0,USERIDHASHTYPE_TUNNELIPV6MCVXLANMODE0*/
        CTC_BMP_SET(ad_mask, DRV_ENUM(DRV_USERIDHASHTYPE_TUNNELIPV4UCVXLANMODE0) + 64);
        CTC_BMP_SET(ad_mask, DRV_ENUM(DRV_USERIDHASHTYPE_TUNNELIPV4UCVXLANMODE0));
        CTC_BMP_SET(ad_mask, DRV_ENUM(DRV_USERIDHASHTYPE_TUNNELIPV6UCVXLANMODE0) + 64);
        CTC_BMP_SET(ad_mask, DRV_ENUM(DRV_USERIDHASHTYPE_TUNNELIPV6UCVXLANMODE0));
        /*drv_type_ipsa, drv_type_ipv6 */
        CTC_BMP_SET(ad_mask, DRV_ENUM(DRV_USERIDHASHTYPE_IPV4PORT) + 64);
        CTC_BMP_SET(ad_mask, DRV_ENUM(DRV_USERIDHASHTYPE_IPV4PORT) );
        CTC_BMP_SET(ad_mask, DRV_ENUM(DRV_USERIDHASHTYPE_IPV6PORT) + 64);
        CTC_BMP_SET(ad_mask, DRV_ENUM(DRV_USERIDHASHTYPE_IPV6PORT) );
        CTC_BMP_SET(ad_mask, DRV_ENUM(DRV_USERIDHASHTYPE_IPV4SA) + 64);
        CTC_BMP_SET(ad_mask, DRV_ENUM(DRV_USERIDHASHTYPE_IPV4SA) );
        CTC_BMP_SET(ad_mask, DRV_ENUM(DRV_USERIDHASHTYPE_IPV6SA) + 64);
        CTC_BMP_SET(ad_mask, DRV_ENUM(DRV_USERIDHASHTYPE_IPV6SA) );

        CTC_BMP_SET(ad_mask, 128);
        CTC_BMP_SET(ad_mask, 129);
        CTC_BMP_UNSET(ad_mask, 130);
        CTC_BMP_UNSET(ad_mask, 131);
        CTC_BMP_SET(ad_mask, 132);
        CTC_BMP_SET(ad_mask, 133);

        SetIpeUserIdMimicryCtl(V, sclMimicryEn_f, &mimicryctl, 0);
        SetIpeUserIdMimicryCtl(A, mimicrySclAdMask_f, &mimicryctl, ad_mask);
        cmd = DRV_IOW(IpeUserIdMimicryCtl_t, DRV_ENTRY_FLAG);
        CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, DRV_CMD_BMP_EN(cmd, MCHIP_FEATURE_PP_EN(lchip,CTC_FEATURE_SCL)), &mimicryctl));

        resved |= (1<<1) | (1<<2)| (1<<3)| (1<<4)| (1<<5)| (1<<8)| (1<<9);
    }
    else
    {
        resved &= ~(1<<1);
    }
    cmd = DRV_IOW(IpeHdrAdjReserved_t, IpeHdrAdjReserved_reserved_f);
    CTC_ERROR_RETURN(DRV_FIELD_IOCTL(lchip, 0, DRV_CMD_BMP_EN(cmd, MCHIP_FEATURE_PP_EN(lchip,CTC_FEATURE_SCL)), &resved));

    return CTC_E_NONE;
}


/*
 * init scl register
 */
STATIC int32
_sys_usw_scl_init_register(uint8 lchip, void* scl_global_cfg)
{
    uint32 cmd   = 0;
    uint32 value = 0;
    IpeUserIdTcamCtl_m ipe_userid_tcam_ctl;
    UserIdTcamCtl_m userid_tcam_ctl;
    sal_memset(&ipe_userid_tcam_ctl, 0, sizeof(ipe_userid_tcam_ctl));
    sal_memset(&userid_tcam_ctl, 0, sizeof(userid_tcam_ctl));

    value = p_usw_scl_master[lchip]->igs_default_base[0];
    cmd   = DRV_IOW(UserIdHashLookupCtl_t, UserIdHashLookupCtl_userIdDefaultEntryBase_f);
    CTC_ERROR_RETURN(DRV_FIELD_IOCTL(lchip, 0, DRV_CMD_BMP_EN(cmd, MCHIP_FEATURE_PP_EN(lchip,CTC_FEATURE_SCL)), &value));
    cmd   = DRV_IOW(UserIdHashLookupCtl_t, UserIdHashLookupCtl_userIdHashLookup0DefaultEntryBase_f);
    CTC_ERROR_RETURN(DRV_FIELD_IOCTL(lchip, 0, DRV_CMD_BMP_EN(cmd, MCHIP_FEATURE_PP_EN(lchip,CTC_FEATURE_SCL)), &value));
    value = p_usw_scl_master[lchip]->igs_default_base[1];
    cmd   = DRV_IOW(UserIdHashLookupCtl_t, UserIdHashLookupCtl_userIdHashLookup1DefaultEntryBase_f);
    CTC_ERROR_RETURN(DRV_FIELD_IOCTL(lchip, 0, DRV_CMD_BMP_EN(cmd, MCHIP_FEATURE_PP_EN(lchip,CTC_FEATURE_SCL)), &value));

    if (DRV_FROM_TMM(lchip))
    {
        cmd   = DRV_IOW(UserIdHashLookupCtl_t, UserIdHashLookupCtl_tunnelId0DefaultEntryBase_f);
        value = p_usw_scl_master[lchip]->tunnel_default_base[0];
        CTC_ERROR_RETURN(DRV_FIELD_IOCTL(lchip, 0, DRV_CMD_BMP_EN(cmd, MCHIP_FEATURE_PP_EN(lchip,CTC_FEATURE_SCL)), &value));
        cmd   = DRV_IOW(UserIdHashLookupCtl_t, UserIdHashLookupCtl_tunnelId1DefaultEntryBase_f);
        value = p_usw_scl_master[lchip]->tunnel_default_base[1];
        CTC_ERROR_RETURN(DRV_FIELD_IOCTL(lchip, 0, DRV_CMD_BMP_EN(cmd, MCHIP_FEATURE_PP_EN(lchip,CTC_FEATURE_SCL)), &value));
    }
    else
    {
        cmd   = DRV_IOW(UserIdHashLookupCtl_t, UserIdHashLookupCtl_tunnelIdDefaultEntryBase_f);
        value = p_usw_scl_master[lchip]->tunnel_default_base[0];
        CTC_ERROR_RETURN(DRV_FIELD_IOCTL(lchip, 0, DRV_CMD_BMP_EN(cmd, MCHIP_FEATURE_PP_EN(lchip,CTC_FEATURE_SCL)), &value));
    }

    cmd = DRV_IOW(IpeUserIdTcamCtl_t, DRV_ENTRY_FLAG);
    SetIpeUserIdTcamCtl(V, array_0_v6BasicKeyIpAddressMode_f, &ipe_userid_tcam_ctl, 0);
    SetIpeUserIdTcamCtl(V, array_1_v6BasicKeyIpAddressMode_f, &ipe_userid_tcam_ctl, 0);
    SetIpeUserIdTcamCtl(V, array_0_v6BasicKeyMode0IpAddr1Encode_f, &ipe_userid_tcam_ctl, 0x1F);
    SetIpeUserIdTcamCtl(V, array_0_v6BasicKeyMode0IpAddr2Encode_f, &ipe_userid_tcam_ctl, 0x1F);
    SetIpeUserIdTcamCtl(V, array_1_v6BasicKeyMode0IpAddr1Encode_f, &ipe_userid_tcam_ctl, 0x1F);
    SetIpeUserIdTcamCtl(V, array_1_v6BasicKeyMode0IpAddr2Encode_f, &ipe_userid_tcam_ctl, 0x1F);

    if (!DRV_FLD_IS_EXISIT(IpeUserIdTcamCtl_t, IpeUserIdTcamCtl_lookupLevel_0_l3Key160ShareFieldMode_f))
    {
        SetIpeUserIdTcamCtl(V, lookupLevel_0_l3Key160ShareFieldModeForUserId_f, &ipe_userid_tcam_ctl, 0);
        SetIpeUserIdTcamCtl(V, lookupLevel_1_l3Key160ShareFieldModeForUserId_f, &ipe_userid_tcam_ctl, 0);
        SetIpeUserIdTcamCtl(V, lookupLevel_0_l3Key160ShareFieldModeForScl_f, &ipe_userid_tcam_ctl, 0);
        SetIpeUserIdTcamCtl(V, lookupLevel_1_l3Key160ShareFieldModeForScl_f, &ipe_userid_tcam_ctl, 0);
        SetIpeUserIdTcamCtl(V, lookupLevel_0_l3Key160ShareFieldModeForTunnelId_f, &ipe_userid_tcam_ctl, 0);
        SetIpeUserIdTcamCtl(V, lookupLevel_1_l3Key160ShareFieldModeForTunnelId_f, &ipe_userid_tcam_ctl, 0);
    }
    else
    {
        /**< [TM] Keep compatibile with D2 */
        SetIpeUserIdTcamCtl(V, lookupLevel_0_l3Key160ShareFieldMode_f, &ipe_userid_tcam_ctl, 0);
        SetIpeUserIdTcamCtl(V, lookupLevel_1_l3Key160ShareFieldMode_f, &ipe_userid_tcam_ctl, 0);
        SetIpeUserIdTcamCtl(V, lookupLevel_0_changeFlowL2KeyUseCvlanMode_f, &ipe_userid_tcam_ctl, 0);
        SetIpeUserIdTcamCtl(V, lookupLevel_1_changeFlowL2KeyUseCvlanMode_f, &ipe_userid_tcam_ctl, 0);
        /**< [TM] Append UDF key 320 Share type: 1-l3l4, 2-l2, 3-l2l3 and default 0-l3l4*/
        SetIpeUserIdTcamCtl(V, lookupLevel_0_udf320KeyShareType_f, &ipe_userid_tcam_ctl, 2);
        SetIpeUserIdTcamCtl(V, lookupLevel_1_udf320KeyShareType_f, &ipe_userid_tcam_ctl, 2);
        /**< [TM] Append tcam2 tcam 3 lookup */
        SetIpeUserIdTcamCtl(V, array_2_v6BasicKeyIpAddressMode_f, &ipe_userid_tcam_ctl, 0);
        SetIpeUserIdTcamCtl(V, array_3_v6BasicKeyIpAddressMode_f, &ipe_userid_tcam_ctl, 0);
        SetIpeUserIdTcamCtl(V, array_2_v6BasicKeyMode0IpAddr1Encode_f, &ipe_userid_tcam_ctl, 0x1F);
        SetIpeUserIdTcamCtl(V, array_2_v6BasicKeyMode0IpAddr2Encode_f, &ipe_userid_tcam_ctl, 0x1F);
        SetIpeUserIdTcamCtl(V, array_3_v6BasicKeyMode0IpAddr1Encode_f, &ipe_userid_tcam_ctl, 0x1F);
        SetIpeUserIdTcamCtl(V, array_3_v6BasicKeyMode0IpAddr2Encode_f, &ipe_userid_tcam_ctl, 0x1F);
        SetIpeUserIdTcamCtl(V, lookupLevel_2_l3Key160ShareFieldMode_f, &ipe_userid_tcam_ctl, 0);
        SetIpeUserIdTcamCtl(V, lookupLevel_3_l3Key160ShareFieldMode_f, &ipe_userid_tcam_ctl, 0);
        SetIpeUserIdTcamCtl(V, lookupLevel_2_changeFlowL2KeyUseCvlanMode_f, &ipe_userid_tcam_ctl, 0);
        SetIpeUserIdTcamCtl(V, lookupLevel_3_changeFlowL2KeyUseCvlanMode_f, &ipe_userid_tcam_ctl, 0);
        SetIpeUserIdTcamCtl(V, lookupLevel_2_udf320KeyShareType_f, &ipe_userid_tcam_ctl, 2);
        SetIpeUserIdTcamCtl(V, lookupLevel_3_udf320KeyShareType_f, &ipe_userid_tcam_ctl, 2);
        /**< [TM] Append prCvlanIdValid, here set "1" to keep compatible with D2
            0:DsSclMacL3Key320.cvlanIdValid = cvlanIdValid
            1:DsSclMacL3Key320.cvlanIdValid = prCvlanIdValid */
        SetIpeUserIdTcamCtl(V, l2L3KeyUsePrCVlanValidInfo_f, &ipe_userid_tcam_ctl, 1);
    }
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, DRV_CMD_BMP_EN(cmd, MCHIP_FEATURE_PP_EN(lchip,CTC_FEATURE_SCL)), &ipe_userid_tcam_ctl));
    /* TMM use UserIdTcamCtl begin */
    SetUserIdTcamCtl(V, array_0_v6BasicKeyIpAddressMode_f, &userid_tcam_ctl, 0);
    SetUserIdTcamCtl(V, array_1_v6BasicKeyIpAddressMode_f, &userid_tcam_ctl, 0);
    SetUserIdTcamCtl(V, array_0_v6BasicKeyMode0IpAddr1Encode_f, &userid_tcam_ctl, 0x1F);
    SetUserIdTcamCtl(V, array_0_v6BasicKeyMode0IpAddr2Encode_f, &userid_tcam_ctl, 0x1F);
    SetUserIdTcamCtl(V, array_1_v6BasicKeyMode0IpAddr1Encode_f, &userid_tcam_ctl, 0x1F);
    SetUserIdTcamCtl(V, array_1_v6BasicKeyMode0IpAddr2Encode_f, &userid_tcam_ctl, 0x1F);

    SetUserIdTcamCtl(V, lookupLevel_0_l3Key160ShareFieldMode_f, &userid_tcam_ctl, 0);
    SetUserIdTcamCtl(V, lookupLevel_1_l3Key160ShareFieldMode_f, &userid_tcam_ctl, 0);
    SetUserIdTcamCtl(V, lookupLevel_0_changeFlowL2KeyUseCvlanMode_f, &userid_tcam_ctl, 0);
    SetUserIdTcamCtl(V, lookupLevel_1_changeFlowL2KeyUseCvlanMode_f, &userid_tcam_ctl, 0);
    /**< [TMM] UDF key 320 Share type: 1-l3l4, 2-l2, 3-l2l3 and default 0-l3l4*/
    SetUserIdTcamCtl(V, lookupLevel_0_udf320KeyShareType_f, &userid_tcam_ctl, 2);
    SetUserIdTcamCtl(V, lookupLevel_1_udf320KeyShareType_f, &userid_tcam_ctl, 2);
    /**< [TMM] prCvlanIdValid */
    /*                  0:DsSclMacL3Key320.cvlanIdValid = cvlanIdValid      */
    /*                  1:DsSclMacL3Key320.cvlanIdValid = prCvlanIdValid    */
    SetUserIdTcamCtl(V, l2L3KeyUsePrCVlanValidInfo_f, &userid_tcam_ctl, 1);
    /**< [TMM] keep compatible with TM */
    SetUserIdTcamCtl(V, sclMacKeyArpPktUseMacField_f, &userid_tcam_ctl, 0);
    SetUserIdTcamCtl(V, sclMacL3KeyArpPktUseMacField_f, &userid_tcam_ctl, 0);
    cmd = DRV_IOW(UserIdTcamCtl_t, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, DRV_CMD_BMP_EN(cmd, MCHIP_FEATURE_PP_EN(lchip,CTC_FEATURE_SCL)), &userid_tcam_ctl));
    /* TMM use UserIdTcamCtl end */
    value = 1;
    cmd = DRV_IOW(IpeUserIdCtl_t, IpeUserIdCtl_layer2TypeUsedAsVlanNum_f);
    CTC_ERROR_RETURN(DRV_FIELD_IOCTL(lchip, 0, DRV_CMD_BMP_EN(cmd, MCHIP_FEATURE_PP_EN(lchip,CTC_FEATURE_SCL)), &value));
    cmd = DRV_IOW(UserIdCtl_t, UserIdCtl_layer2TypeUsedAsVlanNum_f);
    CTC_ERROR_RETURN(DRV_FIELD_IOCTL(lchip, 0, DRV_CMD_BMP_EN(cmd, MCHIP_FEATURE_PP_EN(lchip,CTC_FEATURE_SCL)), &value));
    cmd = DRV_IOW(UserIdCtl_t, UserIdCtl_ingEcidZeroLookupUserId_f);
    CTC_ERROR_RETURN(DRV_FIELD_IOCTL(lchip, 0, DRV_CMD_BMP_EN(cmd, MCHIP_FEATURE_PP_EN(lchip,CTC_FEATURE_SCL)), &value));

//    cmd = DRV_IOW(UserIdCtl_t, IpeUserIdCtl_fidMergeMode_f);/*AT*/ /*DP_TODO*/
//    CTC_ERROR_RETURN(DRV_FIELD_IOCTL(lchip, 0, DRV_CMD_BMP_EN(cmd, MCHIP_FEATURE_PP_EN(lchip,CTC_FEATURE_SCL)), &value));    /*DP_TODO*/

    return CTC_E_NONE;
}

STATIC int32
_sys_usw_scl_create_rsv_group(uint8 lchip)
{

    uint32               index = 0;
    ctc_scl_group_info_t hash_group;
    ctc_scl_group_info_t tcam_group;
    sal_memset(&hash_group, 0, sizeof(ctc_scl_group_info_t));
    sal_memset(&tcam_group, 0, sizeof(ctc_scl_group_info_t));
    hash_group.type = CTC_SCL_GROUP_TYPE_HASH;
    tcam_group.type = CTC_SCL_GROUP_TYPE_NONE;
    hash_group.lchip = lchip;
    tcam_group.lchip = lchip;
    /*reserved hash Group*/
    for (index = CTC_SCL_GROUP_ID_HASH_PORT; index < CTC_SCL_GROUP_ID_HASH_MAX; index++)
    {
         CTC_ERROR_RETURN(_sys_usw_scl_create_group(lchip, index, &hash_group, 1));
    }
    /*reserved hash Group*/
    for (index = 0; index < MCHIP_CAP(SYS_CAP_SCL_HASH_NUM); index += 1)
    {
        tcam_group.priority = index;
        CTC_ERROR_RETURN(_sys_usw_scl_create_group(lchip, CTC_SCL_GROUP_ID_HASH0 + index, &tcam_group, 1));
    }
    /*reserved tcam Group*/
    for (index = 0; index < MCHIP_CAP(SYS_CAP_SCL_IGS_TCAM_NUM); index += 1)
    {
        tcam_group.priority = index;
        CTC_ERROR_RETURN(_sys_usw_scl_create_group(lchip, CTC_SCL_GROUP_ID_TCAM0 + index, &tcam_group, 1));
    }

    return CTC_E_NONE;
}

STATIC int32
_sys_usw_scl_init_opf(uint8 lchip)
{
    uint32               entry_num    = 0;
    uint32               start_offset = 0;
    sys_usw_opf_t opf;

    sal_memset(&opf, 0, sizeof(sys_usw_opf_t));

    CTC_ERROR_RETURN(sys_usw_ftm_query_table_entry_num(lchip, DsVlanActionProfile_t, &entry_num));
    start_offset = MCHIP_CAP(SYS_CAP_SCL_VLAN_ACTION_RESERVE_NUM);
    entry_num   -= MCHIP_CAP(SYS_CAP_SCL_VLAN_ACTION_RESERVE_NUM);

    if (entry_num)
    {
        CTC_ERROR_RETURN(sys_usw_opf_init(lchip, &p_usw_scl_master[lchip]->opf_type_vlan_edit, 1, "opf-type-scl-vlan-edit"));

        opf.pool_type  = p_usw_scl_master[lchip]->opf_type_vlan_edit;
        CTC_ERROR_RETURN(sys_usw_opf_init_offset(lchip, &opf, start_offset, entry_num));
    }

    start_offset = 0;
    entry_num    = SYS_SCL_MAX_INNER_ENTRY_ID - SYS_SCL_MIN_INNER_ENTRY_ID + 1;

    if (entry_num)
    {
        CTC_ERROR_RETURN(sys_usw_opf_init(lchip, &p_usw_scl_master[lchip]->opf_type_entry_id, 1, "opf-type-scl-entry-id"));

        opf.pool_index = 0;
        opf.pool_type  = p_usw_scl_master[lchip]->opf_type_entry_id;
        CTC_ERROR_RETURN(sys_usw_opf_init_offset(lchip, &opf, start_offset, entry_num));
    }

    start_offset = 0;
    if (entry_num)
    {
        CTC_ERROR_RETURN(sys_usw_opf_init(lchip, &p_usw_scl_master[lchip]->opf_type_flow_acl_profile, 1, "opf-type-scl-flow-acl-profile"));

        opf.pool_index = 0;
        opf.pool_type  = p_usw_scl_master[lchip]->opf_type_flow_acl_profile;
        CTC_ERROR_RETURN(sys_usw_opf_init_offset(lchip, &opf, start_offset, MCHIP_CAP(SYS_CAP_SCL_ACL_CONTROL_PROFILE)));
    }

    start_offset = 0;
    if (entry_num)
    {
        CTC_ERROR_RETURN(sys_usw_opf_init(lchip, &p_usw_scl_master[lchip]->opf_type_tunnel_acl_profile, 1, "opf-type-scl-tunnel-acl-profile"));

        opf.pool_index = 0;
        opf.pool_type  = p_usw_scl_master[lchip]->opf_type_tunnel_acl_profile;
        CTC_ERROR_RETURN(sys_usw_opf_init_offset(lchip, &opf, start_offset, MCHIP_CAP(SYS_CAP_SCL_ACL_CONTROL_PROFILE)));
    }

    return CTC_E_NONE;
}


STATIC int32
_sys_usw_scl_mapping_vlan_edit(uint8 lchip,  ctc_scl_vlan_edit_t* p_vlan_edit,void* p_ds_edit)
{
    uint8 op = 0;
    uint8 mo = 0;
    uint8 st = 0;

    sys_usw_scl_vlan_tag_op_translate(lchip, p_vlan_edit->stag_op, &op, &mo);
    SetDsVlanActionProfile(V, sTagAction_f, p_ds_edit, op);
    SetDsVlanActionProfile(V, stagModifyMode_f, p_ds_edit, mo);
    sys_usw_scl_vlan_tag_op_translate(lchip, p_vlan_edit->ctag_op, &op, &mo);
    SetDsVlanActionProfile(V, cTagAction_f, p_ds_edit, op);
    SetDsVlanActionProfile(V, ctagModifyMode_f, p_ds_edit, mo);

    SetDsVlanActionProfile(V, sVlanIdAction_f, p_ds_edit, p_vlan_edit->svid_sl);
    SetDsVlanActionProfile(V, sCosAction_f, p_ds_edit, p_vlan_edit->scos_sl);
    SetDsVlanActionProfile(V, sCfiAction_f, p_ds_edit, p_vlan_edit->scfi_sl);

    SetDsVlanActionProfile(V, cVlanIdAction_f, p_ds_edit, p_vlan_edit->cvid_sl);
    SetDsVlanActionProfile(V, cCosAction_f, p_ds_edit, p_vlan_edit->ccos_sl);
    SetDsVlanActionProfile(V, cCfiAction_f, p_ds_edit, p_vlan_edit->ccfi_sl);

    SetDsVlanActionProfile(V, svlanTpidIndexEn_f, p_ds_edit, (0xFF != p_vlan_edit->tpid_index)?1:0);
    SetDsVlanActionProfile(V, svlanTpidIndex_f, p_ds_edit, (0xFF != p_vlan_edit->tpid_index)?p_vlan_edit->tpid_index:0);

    if(p_vlan_edit->ctag_op == CTC_VLAN_TAG_OP_ADD && p_vlan_edit->stag_op == CTC_VLAN_TAG_OP_ADD)
    {
        SetDsVlanActionProfile(V, ctagAddMode_f, p_ds_edit, 1);
    }
    switch (p_vlan_edit->vlan_domain)
    {
        case CTC_SCL_VLAN_DOMAIN_SVLAN:
            st = 2;
            break;
        case CTC_SCL_VLAN_DOMAIN_CVLAN:
            st = 1;
            break;
        case CTC_SCL_VLAN_DOMAIN_UNCHANGE:
            st = 0;
            break;
        default:
            break;
    }
    SetDsVlanActionProfile(V, outerVlanStatus_f, p_ds_edit, st);
/*
   ctagAddMode_f
   svlanTpidIndexEn_f
   svlanTpidIndex_f
   ds_vlan_action_profile_t
 */
    return CTC_E_NONE;
}

STATIC int32
_sys_usw_scl_mapping_acl_profile(uint8 lchip, uint8 is_tunnel, ctc_acl_property_t* p_acl_profile, void* p_ds_edit)
{
    uint8 offset          = 0;
    uint8 step            = 0;
    uint8 gport_type      = 0;
    uint8 sys_lkup_type   = 0;
    uint8 use_mapped_vlan = 0;


    sys_lkup_type = sys_usw_map_acl_tcam_lkup_type(lchip, p_acl_profile->tcam_lkup_type);

    if (CTC_FLAG_ISSET(p_acl_profile->flag, CTC_ACL_PROP_FLAG_USE_LOGIC_PORT))
    {
        gport_type = DRV_ENUM(DRV_FLOWPORTTYPE_LPORT);
    }
    else if (CTC_FLAG_ISSET(p_acl_profile->flag, CTC_ACL_PROP_FLAG_USE_METADATA))
    {
        gport_type = DRV_ENUM(DRV_FLOWPORTTYPE_METADATA);
    }
    else if (CTC_FLAG_ISSET(p_acl_profile->flag, CTC_ACL_PROP_FLAG_USE_PORT_BITMAP))
    {
        gport_type = DRV_ENUM(DRV_FLOWPORTTYPE_BITMAP);
    }
    else
    {
        gport_type = DRV_ENUM(DRV_FLOWPORTTYPE_GPORT);
    }

    use_mapped_vlan = CTC_FLAG_ISSET(p_acl_profile->flag, CTC_ACL_PROP_FLAG_USE_MAPPED_VLAN);

    if (!is_tunnel)
    {
        step = DsSclAclControlProfile_gAcl_1_aclLookupType_f - DsSclAclControlProfile_gAcl_0_aclLookupType_f;
        offset = step * p_acl_profile->acl_priority;
        SetDsSclAclControlProfile(V, gAcl_0_overwriteIntfAcl_f + offset, p_ds_edit, 1);
        SetDsSclAclControlProfile(V, gAcl_0_aclLookupType_f + offset, p_ds_edit, sys_lkup_type);
        SetDsSclAclControlProfile(V, gAcl_0_aclUseGlobalPortType_f + offset, p_ds_edit, gport_type);
        SetDsSclAclControlProfile(V, gAcl_0_aclUsePIVlan_f + offset, p_ds_edit, use_mapped_vlan);
        SetDsSclAclControlProfile(V, gAcl_0_trustOverwriteLabel_f + offset, p_ds_edit, 1);
        SetDsSclAclControlProfile(V, gAcl_0_overwriteLabelType_f + offset, p_ds_edit, 1);
    }
    else
    {
        step = DsTunnelAclControlProfile_gAcl_1_aclLookupType_f - DsTunnelAclControlProfile_gAcl_0_aclLookupType_f;
        offset = step * p_acl_profile->acl_priority;
        SetDsTunnelAclControlProfile(V, gAcl_0_overwriteIntfAcl_f + offset, p_ds_edit, 1);
        SetDsTunnelAclControlProfile(V, gAcl_0_aclLookupType_f + offset, p_ds_edit, sys_lkup_type);
        SetDsTunnelAclControlProfile(V, gAcl_0_aclUseGlobalPortType_f + offset, p_ds_edit, gport_type);
        SetDsTunnelAclControlProfile(V, gAcl_0_aclUsePIVlan_f + offset, p_ds_edit, use_mapped_vlan);
        SetDsTunnelAclControlProfile(V, gAcl_0_trustDsTunnelLabel_f + offset, p_ds_edit, 1);
    }
    return CTC_E_NONE;
}

#define __scl_internal_api_function__
STATIC int32
_sys_usw_scl_dump_vlan_edit_spool_db(void *node, void* user_date)
{
    sys_traverse_t* p_traverse = (sys_traverse_t*)user_date;
    uint32* p_cnt = (uint32*)p_traverse->data1;
    sal_file_t p_f = (sal_file_t)p_traverse->data;
    ctc_spool_node_t* p_node = (ctc_spool_node_t*)node;
    sys_scl_sp_vlan_edit_t* p_ad = (sys_scl_sp_vlan_edit_t*)p_node->data;
#ifdef CTC_SHELL_DEBUG_ON
    uint8 lchip = p_traverse->value1;
#endif
    if(0xFFFFFFFF == p_node->ref_cnt)
    {
        SYS_DUMP_DB_LOG(p_f, "%-12u%-20u: %-20s\n", (*p_cnt),p_ad->profile_id, "Static");
    }
    else
    {
        SYS_DUMP_DB_LOG(p_f, "%-12u%-20u: %-20u\n", (*p_cnt),p_ad->profile_id, p_node->ref_cnt);
    }
    (*p_cnt)++;
    return CTC_E_NONE;
}
STATIC int32
_sys_usw_scl_dump_acl_profile_spool_db(void *node, void* user_date)
{
    sys_traverse_t* p_traverse = (sys_traverse_t*)user_date;
    uint32* p_cnt = (uint32*)p_traverse->data1;
    sal_file_t p_f = (sal_file_t)p_traverse->data;
    ctc_spool_node_t* p_node = (ctc_spool_node_t*)node;
    sys_scl_action_acl_t* p_ad = (sys_scl_action_acl_t*)p_node->data;
#ifdef CTC_SHELL_DEBUG_ON
    uint8 lchip = p_traverse->value1;
#endif
    if(0xFFFFFFFF == p_node->ref_cnt)
    {
        SYS_DUMP_DB_LOG(p_f, "%-12u%-20u%-20uStatic\n", (*p_cnt),p_ad->profile_id, p_ad->is_scl);
    }
    else
    {
        SYS_DUMP_DB_LOG(p_f, "%-12u%-20u%-20u%-20u\n", (*p_cnt),p_ad->profile_id, p_ad->is_scl, p_node->ref_cnt);
    }
    (*p_cnt)++;
    return CTC_E_NONE;
}

STATIC int32
_sys_usw_scl_dump_hash_ad_spool_db(void *node, void* user_date)
{
    sys_traverse_t* p_traverse = (sys_traverse_t*)user_date;
    uint32* p_cnt = (uint32*)p_traverse->data1;
    sal_file_t p_f = (sal_file_t)p_traverse->data;
    ctc_spool_node_t* p_node = (ctc_spool_node_t*)node;
    sys_scl_sw_igs_ad_t* p_ad = (sys_scl_sw_igs_ad_t*)p_node->data;
#ifdef CTC_SHELL_DEBUG_ON
    uint8 lchip = p_traverse->value1;
#endif
    if(0xFFFFFFFF == p_node->ref_cnt)
    {
        SYS_DUMP_DB_LOG(p_f, "%-12u%-24u%-20u%-20u%-20uStatic\n", (*p_cnt), p_ad->com.action_type, p_ad->com.ad_index, p_ad->com.priority, p_ad->com.is_half);
    }
    else
    {
        SYS_DUMP_DB_LOG(p_f, "%-12u%-24u%-20u%-20u%-20u%-20u\n", (*p_cnt), p_ad->com.action_type, p_ad->com.ad_index, p_ad->com.is_half, p_ad->com.priority, p_node->ref_cnt);
    }
    (*p_cnt)++;
    return CTC_E_NONE;
}
int32
sys_usw_scl_dump_db(uint8 lchip, sal_file_t p_f, ctc_global_dump_db_t* p_dump_param)
{
    uint32 loop = 0;
    char*   action_type_str[SYS_SCL_ACTION_NUM] = {"Ingress", "Egress", "Tunnel", "Flow","Mpls"};
    sys_scl_sw_block_t* pb = NULL;
    sys_traverse_t  param;
    uint32  spool_cnt = 1;
    ctc_spool_t* p_ad = NULL;

    SYS_SCL_INIT_CHECK();
    SYS_SCL_LOCK(lchip);

    SYS_DUMP_DB_LOG(p_f, "%s\n", "# SCL");
    SYS_DUMP_DB_LOG(p_f, "%s\n", "{");
    SYS_DUMP_DB_LOG(p_f, "%s\n", "Master config:");
    SYS_DUMP_DB_LOG(p_f, "%s\n", "------------------------------------------------------");
    SYS_DUMP_DB_LOG(p_f, "%-36s: %u\n","Opf type of vlan edit", p_usw_scl_master[lchip]->opf_type_vlan_edit);
    SYS_DUMP_DB_LOG(p_f, "%-36s: %u\n","Opf type of entry id", p_usw_scl_master[lchip]->opf_type_entry_id);
    SYS_DUMP_DB_LOG(p_f, "%-36s: %u\n","Opf type of flow acl profile", p_usw_scl_master[lchip]->opf_type_flow_acl_profile);
    SYS_DUMP_DB_LOG(p_f, "%-36s: %u\n","Opf type of tunnel acl profile", p_usw_scl_master[lchip]->opf_type_tunnel_acl_profile);

    SYS_DUMP_DB_LOG(p_f, "%-36s: %u %u\n","Ingress default entry base", p_usw_scl_master[lchip]->igs_default_base[0], p_usw_scl_master[lchip]->igs_default_base[1]);
    SYS_DUMP_DB_LOG(p_f, "%-36s: %u\n","Hash Mode", p_usw_scl_master[lchip]->hash_mode);
    SYS_DUMP_DB_LOG(p_f, "%-36s: %u\n","Tunnel default entry base", p_usw_scl_master[lchip]->tunnel_default_base[0]);
    if (DRV_FROM_TMM(lchip))
    {
        SYS_DUMP_DB_LOG(p_f, "%-36s: %u\n","Tunnel1 default entry base", p_usw_scl_master[lchip]->tunnel_default_base[1]);
    }

    SYS_DUMP_DB_LOG(p_f, "Entry Count\n");
    SYS_DUMP_DB_LOG(p_f, "%s\n", "------------------------------------------------------");
    SYS_DUMP_DB_LOG(p_f, "%-24s%-24s\n","Action Type", "Entry count");
    SYS_DUMP_DB_LOG(p_f, "%s\n", "------------------------------------------------------");
    for(loop=0; loop < SYS_SCL_ACTION_NUM; loop++)
    {
        SYS_DUMP_DB_LOG(p_f, "%-24s%-24u\n",action_type_str[loop], p_usw_scl_master[lchip]->entry_count[0][loop]+p_usw_scl_master[lchip]->entry_count[1][loop]);
    }

    SYS_DUMP_DB_LOG(p_f, "\n%-36s\n","Block information:");
    SYS_DUMP_DB_LOG(p_f, "%s\n", "--------------------------------------------------------------------------------------------");
    SYS_DUMP_DB_LOG(p_f, "%-16s%-16s%-16s\n","Block ID", "Entry count","Free count");
    SYS_DUMP_DB_LOG(p_f, "%-16s%-16s%-16s%-16s%-16s%-16s\n","","Key size","Start offset", "Sub cnt","Sub free cnt","Reserve cnt");
    SYS_DUMP_DB_LOG(p_f, "%s\n", "--------------------------------------------------------------------------------------------");
    for(loop = 0; loop < MCHIP_CAP(SYS_CAP_SCL_TCAM_NUM); loop++)
    {
        pb = &p_usw_scl_master[lchip]->fpa_block[loop];
        SYS_DUMP_DB_LOG(p_f, "\n%-16u%-16u%-16u\n", loop, pb->fpab.entry_count, pb->fpab.free_count);

        if(pb->fpab.sub_entry_count[CTC_FPA_KEY_SIZE_80])
        {
            SYS_DUMP_DB_LOG(p_f, "%-16s%-16s%-16u%-16u%-16u%-16u\n", "","80 bits",pb->fpab.start_offset[CTC_FPA_KEY_SIZE_80],\
                pb->fpab.sub_entry_count[CTC_FPA_KEY_SIZE_80],pb->fpab.sub_free_count[CTC_FPA_KEY_SIZE_80],pb->fpab.sub_rsv_count[CTC_FPA_KEY_SIZE_80]);
        }
        else
        {
            SYS_DUMP_DB_LOG(p_f, "%-16s%-16s%-16u%-16u%-16u%-16u\n", "","160 bits",pb->fpab.start_offset[CTC_FPA_KEY_SIZE_160],\
                pb->fpab.sub_entry_count[CTC_FPA_KEY_SIZE_160],pb->fpab.sub_free_count[CTC_FPA_KEY_SIZE_160],pb->fpab.sub_rsv_count[CTC_FPA_KEY_SIZE_160]);
            SYS_DUMP_DB_LOG(p_f, "%-16s%-16s%-16u%-16u%-16u%-16u\n", "","320 bits",pb->fpab.start_offset[CTC_FPA_KEY_SIZE_320],\
                pb->fpab.sub_entry_count[CTC_FPA_KEY_SIZE_320],pb->fpab.sub_free_count[CTC_FPA_KEY_SIZE_320],pb->fpab.sub_rsv_count[CTC_FPA_KEY_SIZE_320]);
            SYS_DUMP_DB_LOG(p_f, "%-16s%-16s%-16u%-16u%-16u%-16u\n", "","640 bits",pb->fpab.start_offset[CTC_FPA_KEY_SIZE_640],\
                pb->fpab.sub_entry_count[CTC_FPA_KEY_SIZE_640],pb->fpab.sub_free_count[CTC_FPA_KEY_SIZE_640],pb->fpab.sub_rsv_count[CTC_FPA_KEY_SIZE_640]);
        }

    }
    SYS_DUMP_DB_LOG(p_f, "\n");

    SYS_DUMP_DB_LOG(p_f, "%-36s\n","Hash select information:");
    SYS_DUMP_DB_LOG(p_f, "%s\n", "-----------------------------------------------");
    SYS_DUMP_DB_LOG(p_f, "%-12s%-14s\n","Hash sel id", "Profile count");
    SYS_DUMP_DB_LOG(p_f, "%s\n", "-----------------------------------------------");

    for(loop=0; loop < MCHIP_CAP(SYS_CAP_SCL_HASH_SEL_ID_NUM); loop++)
    {
        SYS_DUMP_DB_LOG(p_f, "%-12u%-14u\n", loop, p_usw_scl_master[SYS_PP_BASE(lchip)]->hash_sel_profile_count[loop]);
    }

    SYS_DUMP_DB_LOG(p_f, "\n");

    sys_usw_opf_fprint_alloc_used_info(lchip, p_usw_scl_master[lchip]->opf_type_vlan_edit, p_f);
    SYS_DUMP_DB_LOG(p_f, "\n");
    sys_usw_opf_fprint_alloc_used_info(lchip, p_usw_scl_master[lchip]->opf_type_entry_id, p_f);
    SYS_DUMP_DB_LOG(p_f, "\n");
    sys_usw_opf_fprint_alloc_used_info(lchip, p_usw_scl_master[lchip]->opf_type_flow_acl_profile, p_f);
    SYS_DUMP_DB_LOG(p_f, "\n");
    sys_usw_opf_fprint_alloc_used_info(lchip, p_usw_scl_master[lchip]->opf_type_tunnel_acl_profile, p_f);
    SYS_DUMP_DB_LOG(p_f, "\n");

    if(p_usw_scl_master[lchip]->vlan_edit_spool->count)
    {
        spool_cnt = 1;
        sal_memset(&param, 0, sizeof(param));
        param.data = (void*)p_f;
        param.data1 = (void*)&spool_cnt;
        param.value1 = lchip;

        SYS_DUMP_DB_LOG(p_f, "\nSpool type: %s\n","Vlan edit spool (Table Name: DsVlanActionProfile)");
        SYS_DUMP_DB_LOG(p_f, "%s\n", "-------------------------------------------------------------");
        SYS_DUMP_DB_LOG(p_f, "%-12s%-20s: %-20s\n", "Node","Index", "Ref count");
        SYS_DUMP_DB_LOG(p_f, "%s\n", "-------------------------------------------------------------");
        ctc_spool_traverse(p_usw_scl_master[lchip]->vlan_edit_spool, (spool_traversal_fn)_sys_usw_scl_dump_vlan_edit_spool_db , (void*)(&param));
    }

    if(p_usw_scl_master[lchip]->acl_spool->count)
    {
        spool_cnt = 1;
        sal_memset(&param, 0, sizeof(param));
        param.data = (void*)p_f;
        param.data1 = (void*)&spool_cnt;
        param.value1 = lchip;

        SYS_DUMP_DB_LOG(p_f, "\nSpool type: %s\n","Acl profile spool (Table Name: DsSclAclControlProfile)");
        SYS_DUMP_DB_LOG(p_f, "%s\n", "--------------------------------------------------------------------");
        SYS_DUMP_DB_LOG(p_f, "%-12s%-20s%-20s%-20s\n", "Node","Table index", "Is Scl", "Ref count");
        SYS_DUMP_DB_LOG(p_f, "%s\n", "--------------------------------------------------------------------");
        ctc_spool_traverse(p_usw_scl_master[lchip]->acl_spool, (spool_traversal_fn)_sys_usw_scl_dump_acl_profile_spool_db , (void*)(&param));
    }
    for(loop=0; loop < 2*SYS_SCL_SW_AD_TYPE_IGS_MAX; loop++)
    {
        spool_cnt = 1;
        sal_memset(&param, 0, sizeof(param));
        param.data = (void*)p_f;
        param.data1 = (void*)&spool_cnt;
        param.value1 = lchip;
        p_ad = p_usw_scl_master[lchip]->ad_spool[loop];
        if(p_ad && p_ad->count)
        {
            SYS_DUMP_DB_LOG(p_f, "\nSpool type: Ad Spool %u\n", loop);
            SYS_DUMP_DB_LOG(p_f, "%s\n", "--------------------------------------------------------------------------------------------------");
            SYS_DUMP_DB_LOG(p_f, "%-12s%-20s%-20s%-20s%-20s%-20s\n", "Node","Action Type","Profile ID","Is Half", "Priority","Ref count");
            SYS_DUMP_DB_LOG(p_f, "%s\n", "--------------------------------------------------------------------------------------------------");
            ctc_spool_traverse(p_ad, (spool_traversal_fn)_sys_usw_scl_dump_hash_ad_spool_db , (void*)(&param));
        }
    }
    SYS_DUMP_DB_LOG(p_f, "%s\n", "}");

    SYS_SCL_UNLOCK(lchip);
    return CTC_E_NONE;
}
int32
sys_usw_scl_ftm_scl_cb(uint8 lchip, sys_ftm_specs_info_t* specs_info)
{
    CTC_PTR_VALID_CHECK(specs_info);
    SYS_SCL_INIT_CHECK();

    SYS_SCL_LOCK(lchip);
    specs_info->used_size = p_usw_scl_master[lchip]->entry_count[0][SYS_SCL_ACTION_INGRESS] + 
                            p_usw_scl_master[lchip]->entry_count[1][SYS_SCL_ACTION_INGRESS];
    SYS_SCL_UNLOCK(lchip);

    return CTC_E_NONE;
}

int32
sys_usw_scl_ftm_tunnel_cb(uint8 lchip, sys_ftm_specs_info_t* specs_info)
{
    CTC_PTR_VALID_CHECK(specs_info);
    SYS_SCL_INIT_CHECK();

    SYS_SCL_LOCK(lchip);
    specs_info->used_size = p_usw_scl_master[lchip]->entry_count[0][SYS_SCL_ACTION_TUNNEL]+
                            p_usw_scl_master[lchip]->entry_count[1][SYS_SCL_ACTION_TUNNEL];
    SYS_SCL_UNLOCK(lchip);

    return CTC_E_NONE;
}

int32
sys_usw_scl_ftm_flow_cb(uint8 lchip, sys_ftm_specs_info_t* specs_info)
{
    CTC_PTR_VALID_CHECK(specs_info);
    SYS_SCL_INIT_CHECK();

    SYS_SCL_LOCK(lchip);
    specs_info->used_size = p_usw_scl_master[lchip]->entry_count[0][SYS_SCL_ACTION_FLOW]+
                            p_usw_scl_master[lchip]->entry_count[1][SYS_SCL_ACTION_FLOW];
    SYS_SCL_UNLOCK(lchip);

    return CTC_E_NONE;
}

int32
sys_usw_scl_ftm_xlate_cb(uint8 lchip, sys_ftm_specs_info_t* specs_info)
{
    CTC_PTR_VALID_CHECK(specs_info);
    SYS_SCL_INIT_CHECK();

    SYS_SCL_LOCK(lchip);
    specs_info->used_size = p_usw_scl_master[lchip]->entry_count[0][SYS_SCL_ACTION_EGRESS] +
                            p_usw_scl_master[lchip]->entry_count[1][SYS_SCL_ACTION_EGRESS];
    SYS_SCL_UNLOCK(lchip);

    return CTC_E_NONE;
}

int32
sys_usw_scl_ftm_ingress_tcam_cb(uint8 lchip, sys_ftm_specs_info_t* specs_info)
{
    CTC_PTR_VALID_CHECK(specs_info);
    SYS_SCL_INIT_CHECK();

    SYS_SCL_LOCK(lchip);
    specs_info->used_size = (p_usw_scl_master[lchip]->fpa_block[DRV_IS_DUET2(lchip)? 0: 2].fpab.entry_count +
                            p_usw_scl_master[lchip]->fpa_block[DRV_IS_DUET2(lchip)? 1: 3].fpab.entry_count - 
                            p_usw_scl_master[lchip]->fpa_block[DRV_IS_DUET2(lchip)? 0: 2].fpab.free_count -
                            p_usw_scl_master[lchip]->fpa_block[DRV_IS_DUET2(lchip)? 1: 3].fpab.free_count)/2;
    SYS_SCL_UNLOCK(lchip);

    return CTC_E_NONE;
}

int32
_sys_usw_scl_init_wb(uint8 lchip)
{
   ctc_wb_appid_t  appid;
   sal_memset(&appid,0,sizeof(appid));

   appid.app_id = lchip << 16 | CTC_WB_APPID(CTC_FEATURE_SCL, SYS_WB_APPID_SCL_SUBID_MASTER) ;
   appid.entry_num = MCHIP_CAP(SYS_CAP_SCL_TCAM_NUM)*SYS_WB_FPA_KEY_SIZE_NUM;
   appid.entry_size  = sizeof(sys_wb_scl_master_t);
   appid.rt_en = 0;
   ctc_wb_add_appid( lchip, &appid);

   appid.app_id = lchip << 16 | CTC_WB_APPID(CTC_FEATURE_SCL, SYS_WB_APPID_SCL_SUBID_GROUP) ;
   appid.entry_num = SYS_FTM_SPEC(lchip, CTC_FTM_SPEC_SCL_GROUP);
   appid.entry_size  = sizeof(sys_wb_scl_group_t);
   appid.rt_en = 0;
   ctc_wb_add_appid( lchip, &appid);
#if 0
   appid.app_id = lchip << 16 | CTC_WB_APPID(CTC_FEATURE_SCL, SYS_WB_APPID_SCL_SUBID_ENTRY) ;
    appid.entry_num = MCHIP_CAP(SYS_CAP_SPEC_SCL_ENTRY_NUM);
    if (DRV_FROM_TMM(lchip))
    {
        uint32 egs_tcam0 = 0, egs_tcam1 = 0;
        sys_usw_ftm_query_table_entry_num(lchip, DsEgressScl0TcamKey_t, &egs_tcam0);
        sys_usw_ftm_query_table_entry_num(lchip, DsEgressScl1TcamKey_t, &egs_tcam1);
        appid.entry_num -= (egs_tcam0 + egs_tcam1);
    }
   appid.entry_size  = sizeof(sys_wb_scl_entry_t);
   appid.rt_en = 0;
   ctc_wb_add_appid( lchip, &appid);
#endif
   appid.app_id = lchip << 16 | CTC_WB_APPID(CTC_FEATURE_SCL, SYS_WB_APPID_SCL_SUBID_IGS_HASH_ENTRY) ;
   appid.entry_num = SYS_FTM_SPEC(lchip, CTC_FTM_SPEC_SCL);
   appid.entry_size  = sizeof(sys_wb_scl_igs_hash_entry_t);
   appid.rt_en = 0;
   ctc_wb_add_appid( lchip, &appid);

   appid.app_id = lchip << 16 | CTC_WB_APPID(CTC_FEATURE_SCL, SYS_WB_APPID_SCL_SUBID_IGS_TCAM_ENTRY) ;
   appid.entry_num = SYS_FTM_SPEC(lchip, CTC_FTM_SPEC_SCL_TCAM);
   appid.entry_size  = sizeof(sys_wb_scl_igs_tcam_entry_t);
   appid.rt_en = 0;
   ctc_wb_add_appid( lchip, &appid);

   appid.app_id = lchip << 16 | CTC_WB_APPID(CTC_FEATURE_SCL, SYS_WB_APPID_SCL_SUBID_EGS_HASH_ENTRY) ;
   appid.entry_num = SYS_FTM_SPEC(lchip, CTC_FTM_SPEC_VLAN_XLATE); 
   appid.entry_size  = sizeof(sys_wb_scl_egs_entry_t);
   appid.rt_en = 0;
   ctc_wb_add_appid( lchip, &appid);


   appid.app_id = lchip << 16 | CTC_WB_APPID(CTC_FEATURE_SCL, SYS_WB_APPID_SCL_SUBID_DEFAULT_ENTRY) ;
   appid.entry_num = SYS_WB_SCL_SUBID_DEFAULT_ENTRY_NUM;
   appid.entry_size  = sizeof(sys_wb_scl_igs_hash_entry_t);
   appid.rt_en = 0;
   ctc_wb_add_appid( lchip, &appid);
   if(DRV_FROM_AT(lchip))
   {
       appid.app_id = lchip << 16 | CTC_WB_APPID(CTC_FEATURE_SCL, SYS_WB_APPID_SCL_SUBID_FLEX_KEY) ;
       appid.entry_num = SYS_WB_SCL_SUBID_FLEX_KEY_NUM;
       appid.entry_size  = sizeof(sys_wb_scl_flex_key_t);
       appid.rt_en = 0;
       ctc_wb_add_appid( lchip, &appid);
   }


   return 0;

}
void
sys_usw_scl_show_kset(uint8 lchip, ctc_scl_flex_key_t * scl_flex_key)
{
    uint16 loop = 0;

    SYS_SCL_DBG_OUT(CTC_DEBUG_LEVEL_DUMP, "%-8s  %-24s\n", "ID", "FIELD");
    SYS_SCL_DBG_OUT(CTC_DEBUG_LEVEL_DUMP, "----------------------------------------------------\n");
    for (loop = 0; loop < CTC_FIELD_KEY_NUM; loop++)
    {
        if (!CTC_BMP_ISSET(scl_flex_key->kset.w, loop))
        {
            continue;
        }
        SYS_SCL_DBG_OUT(CTC_DEBUG_LEVEL_DUMP, "%-8d  %-24s\n", loop, ifp_field_str[loop]);
    }
    SYS_SCL_DBG_OUT(CTC_DEBUG_LEVEL_DUMP, "\n");
    //SYS_ACL_DBG_OUT(CTC_DEBUG_LEVEL_DUMP, "%-16s: %s\n", "origin key type", key_type_str[acl_flex_key->origin_key_type]);
}

STATIC int32
_sys_usw_scl_kset_deinit(uint8 lchip)
{
    uint8 loop_i = 0;
    uint8 loop_j = 0;
    if (!p_usw_scl_master[lchip]->kset_db)
    {
        return CTC_E_NONE;
    }
    for (loop_i = CTC_INGRESS; loop_i < CTC_BOTH_DIRECTION; loop_i++)
    {
        for (loop_j = 0; loop_j < SYS_SCL_KEY_NUM; loop_j++)
        {
            if (p_usw_scl_master[lchip]->kset_db[loop_i][loop_j])
            {
                mem_free(p_usw_scl_master[lchip]->kset_db[loop_i][loop_j]);
            }
        }
        if (p_usw_scl_master[lchip]->kset_db[loop_i])
        {
            mem_free(p_usw_scl_master[lchip]->kset_db[loop_i]);
        }
    }
    if (p_usw_scl_master[lchip]->kset_db)
    {
        mem_free(p_usw_scl_master[lchip]->kset_db);
    }
    return CTC_E_NONE;
}

STATIC int32
_sys_usw_scl_kset_init(uint8 lchip)
{
    uint8 loop_i = 0;
    uint8 loop_j = 0;
    uint32 key_type_bmp[CTC_BOTH_DIRECTION][CTC_B2W_SIZE(SYS_SCL_KEY_NUM)];
    sys_scl_kset_t* p_kset = NULL;

    sal_memset(key_type_bmp, 0, sizeof(key_type_bmp));
    p_usw_scl_master[lchip]->kset_db = mem_malloc(MEM_SCL_MODULE, CTC_BOTH_DIRECTION*sizeof(void*));
    if (NULL == p_usw_scl_master[lchip]->kset_db)
    {
        return CTC_E_NO_MEMORY;
    }
    for (loop_i = CTC_INGRESS; loop_i < CTC_BOTH_DIRECTION; loop_i++)
    {
        p_usw_scl_master[lchip]->kset_db[loop_i] = mem_malloc(MEM_SCL_MODULE, SYS_SCL_KEY_NUM*sizeof(void*));
        if (NULL == p_usw_scl_master[lchip]->kset_db[loop_i])
        {
            goto error0;
        }
        for (loop_j = 0; loop_j < SYS_SCL_KEY_NUM; loop_j++)
        {
            MALLOC_ZERO(MEM_SCL_MODULE, p_kset, sizeof(sys_scl_kset_t));
            if (NULL == p_kset)
            {
                goto error0;
            }
            p_usw_scl_master[lchip]->kset_db[loop_i][loop_j] = p_kset;
        }
    }
    if (DRV_FROM_AT(lchip))
    {
        #include "arctic/sys_at_scl_kset.h"
    }

    for (loop_i = CTC_INGRESS; loop_i < CTC_BOTH_DIRECTION; loop_i++)
    {
        for (loop_j = 0; loop_j < SYS_SCL_KEY_NUM; loop_j++)
        {
            if (!CTC_BMP_ISSET(key_type_bmp[loop_i], loop_j))
            {
                mem_free(p_usw_scl_master[lchip]->kset_db[loop_i][loop_j]);
            }
        }
    }

    return CTC_E_NONE;
error0:
    _sys_usw_scl_kset_deinit(lchip);
    return CTC_E_NO_MEMORY;
}

int32
sys_usw_scl_init(uint8 lchip, void* scl_global_cfg)
{
    uint32      ad_num[2] = {0};
    uint32      ad_tbl[2] = {DsUserId_t, DsUserId1_t};
    uint32      ad_tunnel[2] = {DsTunnelId_t, DsTunnelId1_t};
    uint32      vedit_entry_size        = 0;
    int32       ret    = 0;
    uint32      cmd    = 0;
    uint32      value  = 0;
    uint32      offset = 0;
    uint32      loop   = 0;
    uint32      entry_num = 0;
    uint32      spec_type = 0;
    uint32      spec_value = 0;
    ctc_spool_t spool;
    uint16      def_tunnel_num = 0;
    uint8       index = 0;
    uint8       size[SYS_SCL_SW_AD_TYPE_IGS_MAX] = {CTC_OFFSET_OF(sys_scl_sw_igs_ad0_t, calc_key_len),
                                                 CTC_OFFSET_OF(sys_scl_sw_igs_ad1_t, calc_key_len),
                                                 CTC_OFFSET_OF(sys_scl_sw_igs_ad2_t, calc_key_len),
                                                 CTC_OFFSET_OF(sys_scl_sw_igs_ad3_t, calc_key_len),
                                                 CTC_OFFSET_OF(sys_scl_sw_igs_ad_t, calc_key_len)};

    uint32      entry_num1 = 0;
    uint32      ceth_type_size = 0;
    drv_ftm_info_detail_t p_ftm_info;

    LCHIP_CHECK(lchip);
    /* check init */
    if (NULL != p_usw_scl_master[lchip])
    {
        return CTC_E_NONE;
    }
    SYS_VCHIP_MASTER_INIT(lchip, p_usw_scl_master, CTC_FEATURE_SCL);
    /* malloc master */
    MALLOC_ZERO(MEM_SCL_MODULE, p_usw_scl_master[lchip], sizeof(sys_scl_master_t));
    if (NULL == p_usw_scl_master[lchip])
    {
        SYS_SCL_DBG_OUT(CTC_DEBUG_LEVEL_ERROR, " No memory \n");
        return CTC_E_NO_MEMORY;

    }

    sal_memset(&p_ftm_info, 0, sizeof(drv_ftm_info_detail_t));
    p_ftm_info.info_type = DRV_FTM_INFO_TYPE_SCL_MODE;
    CTC_ERROR_RETURN(drv_usw_ftm_get_info_detail(lchip, &p_ftm_info));
    if (DRV_FROM_TMM(lchip))
    {
        p_usw_scl_master[lchip]->hash_mode = 1;
    }
    else if (1 == MCHIP_CAP(SYS_CAP_SCL_HASH_NUM))       /*only one hash*/
    {
        p_usw_scl_master[lchip]->hash_mode = 2;
    }
    else if (2 == MCHIP_CAP(SYS_CAP_SCL_HASH_NUM) && !p_ftm_info.scl_mode)       /*two hash, incompatible mode*/
    {
        p_usw_scl_master[lchip]->hash_mode = 1;
    }
    else
    {
        /*default: two hash, compatible mode*/
    }

    /* get Hw table size */
    if (DRV_FROM_TMM(lchip))
    {
        CTC_ERROR_GOTO(sys_usw_ftm_query_table_entry_num(lchip, DsEgressScl0PortHashKey_t, &(p_usw_scl_master[lchip]->egs_entry_num[0])), ret, error0);
        CTC_ERROR_GOTO(sys_usw_ftm_query_table_entry_num(lchip, DsEgressScl1PortHashKey_t, &(p_usw_scl_master[lchip]->egs_entry_num[1])), ret, error0);
        CTC_ERROR_GOTO(sys_usw_ftm_query_table_entry_num(lchip, DsUserId0PortHashKey_t, &(p_usw_scl_master[lchip]->entry_num[0])), ret, error0);
        CTC_ERROR_GOTO(sys_usw_ftm_query_table_entry_num(lchip, DsUserId1PortHashKey_t, &(p_usw_scl_master[lchip]->entry_num[1])), ret, error0);
    }
    else
    {
        CTC_ERROR_GOTO(sys_usw_ftm_query_table_entry_num(lchip, DsEgressXcOamPortHashKey_t, &(p_usw_scl_master[lchip]->egs_entry_num[0])), ret, error0);
        CTC_ERROR_GOTO(sys_usw_ftm_query_table_entry_num(lchip, DsUserIdPortHashKey_t, &(p_usw_scl_master[lchip]->entry_num[0])), ret, error0);
        if(DRV_IS_TSINGMA(lchip) && 1 ==p_usw_scl_master[lchip]->hash_mode)
        {
            CTC_ERROR_GOTO(sys_usw_ftm_query_table_entry_num(lchip, DsUserId1PortHashKey_t, &(p_usw_scl_master[lchip]->entry_num[1])), ret, error0);
        }
    }
    CTC_ERROR_GOTO(sys_usw_ftm_query_table_entry_num(lchip, ad_tbl[0], &ad_num[0]), ret, error0);
    CTC_ERROR_GOTO(sys_usw_ftm_query_table_entry_num(lchip, ad_tbl[1], &ad_num[1]), ret, error0);
    CTC_ERROR_GOTO(sys_usw_ftm_query_table_entry_num(lchip, DsVlanActionProfile_t, &vedit_entry_size), ret, error0);

    /*init DB*/
    p_usw_scl_master[lchip]->group = ctc_hash_create(SYS_SCL_GROUP_HASH_SIZE/CTC_HASH_32_BLOCK_SIZE,
                                        CTC_HASH_32_BLOCK_SIZE,
                                        (hash_key_fn) _sys_usw_scl_group_hash_make,
                                        (hash_cmp_fn) _sys_usw_scl_group_hash_compare);
    if (NULL == p_usw_scl_master[lchip]->group)
    {
        ret = CTC_E_INIT_FAIL;
        goto error0;
    }

    p_usw_scl_master[lchip]->entry = ctc_hash_create(SYS_SCL_ENTRY_HASH_SIZE/CTC_HASH_1K_BLOCK_SIZE,
                                            CTC_HASH_1K_BLOCK_SIZE,
                                            (hash_key_fn) _sys_usw_scl_entry_hash_make,
                                            (hash_cmp_fn) _sys_usw_scl_entry_hash_compare);
    if (NULL == p_usw_scl_master[lchip]->entry)
    {
        ret = CTC_E_INIT_FAIL;
        goto error1;
    }

    p_usw_scl_master[lchip]->hash_key_entry = ctc_hash_create(SYS_SCL_ENTRY_HASH_SIZE/CTC_HASH_1K_BLOCK_SIZE,
                                                   CTC_HASH_1K_BLOCK_SIZE,
                                                   (hash_key_fn) _sys_usw_scl_hash_key_entry_make,
                                                   (hash_cmp_fn) _sys_usw_scl_hash_key_entry_compare);
    if (NULL == p_usw_scl_master[lchip]->hash_key_entry)
    {
        ret = CTC_E_INIT_FAIL;
        goto error2;
    }

    p_usw_scl_master[lchip]->tcam_entry_by_key = ctc_hash_create(SYS_SCL_TCAM_ENTRY_BY_KEY_HASH_SIZE/CTC_HASH_32_BLOCK_SIZE, CTC_HASH_32_BLOCK_SIZE,
                                                   (hash_key_fn) _sys_usw_scl_tcam_entry_by_key_hash_make,
                                                   (hash_cmp_fn) _sys_usw_scl_tcam_entry_by_key_hash_compare);
    if (NULL == p_usw_scl_master[lchip]->tcam_entry_by_key)
    {
        ret = CTC_E_INIT_FAIL;
        goto error3;
    }

    if(MCHIP_SCL(lchip)->entry_pp_hash_init && MCHIP_FEATURE_PP_EN(lchip, CTC_FEATURE_SCL))
    {
        CTC_ERROR_GOTO(MCHIP_SCL(lchip)->entry_pp_hash_init(lchip),ret,error3);
    }

    if (SYS_VCHIP_PP_IS_NOT_BASE(lchip))
    {
        p_usw_scl_master[lchip]->flex_key_vec = p_usw_scl_master[drv_vchip_get_pp_base(lchip)]->flex_key_vec;
        p_usw_scl_master[lchip]->kset_db = p_usw_scl_master[drv_vchip_get_pp_base(lchip)]->kset_db;
    }
    else if (DRV_FROM_AT(lchip))
    {
        CTC_ERROR_GOTO(_sys_usw_scl_kset_init(lchip), ret, error3);
        p_usw_scl_master[lchip]->flex_key_vec = ctc_vector_init(CTC_VEC_BLOCK_NUM(SYS_SCL_FLEX_KEY_VEC_SIZE, SYS_SCL_FLEX_KEY_VEC_BLOCK_SIZE), SYS_SCL_FLEX_KEY_VEC_BLOCK_SIZE);
        if (NULL == p_usw_scl_master[lchip]->flex_key_vec)
        {
            ret = CTC_E_INIT_FAIL;
            goto free_kset;
        }

    }

    p_usw_scl_master[lchip]->default_entry = ctc_vector_init(CTC_VEC_BLOCK_NUM(SYS_SCL_DEF_ENTRY_VEC_SIZE, SYS_SCL_DEF_ENTRY_VEC_BLOCK_SIZE), SYS_SCL_DEF_ENTRY_VEC_BLOCK_SIZE);
    if (NULL == p_usw_scl_master[lchip]->default_entry)
    {
        ret = CTC_E_INIT_FAIL;
        goto free_flex_key;
    }
    /*vlan edit spool*/
    sal_memset(&spool, 0, sizeof(ctc_spool_t));
    spool.lchip = lchip;
    spool.block_num = vedit_entry_size / SYS_SCL_VLAN_EDIT_SPOOL_BLOCK_SIZE;
    spool.block_size = SYS_SCL_VLAN_EDIT_SPOOL_BLOCK_SIZE;
    spool.max_count = MCHIP_CAP(SYS_CAP_LOCAL_SLICE_NUM)*vedit_entry_size;
    spool.user_data_size = sizeof(sys_scl_sp_vlan_edit_t);
    spool.spool_key = (hash_key_fn) _sys_usw_scl_vlan_edit_spool_make;
    spool.spool_cmp = (hash_cmp_fn) _sys_usw_scl_vlan_edit_spool_compare;
    spool.spool_alloc = (spool_alloc_fn)_sys_usw_scl_vlan_edit_spool_alloc_index;
    spool.spool_free= (spool_free_fn)_sys_usw_scl_vlan_edit_spool_free_index;
    p_usw_scl_master[lchip]->vlan_edit_spool = ctc_spool_create(&spool);
    if (NULL == p_usw_scl_master[lchip]->vlan_edit_spool)
    {
        ret = CTC_E_INIT_FAIL;
        goto free_default_entry;
    }

    for (index=0; index<MCHIP_CAP(SYS_CAP_SCL_HASH_NUM); index++)
    {
        if(ad_num[index] == 0)
        {
            continue;
        }
        /*Ad spool*/
        spool.lchip = lchip;
        spool.block_num = ad_num[index] / SYS_SCL_AD_SPOOL_BLOCK_SIZE;
        spool.block_size = SYS_SCL_AD_SPOOL_BLOCK_SIZE;
        spool.max_count = ad_num[index];
        spool.spool_key = (hash_key_fn) _sys_usw_scl_ad_spool_make;
        spool.spool_cmp = (hash_cmp_fn) _sys_usw_scl_ad_spool_compare;
        spool.spool_alloc = (spool_alloc_fn)_sys_usw_scl_ad_spool_alloc_index;
        spool.spool_free= (spool_free_fn)_sys_usw_scl_ad_spool_free_index;
        for (loop = 0; loop < SYS_SCL_SW_AD_TYPE_IGS_MAX; loop++)
        {
            spool.user_data_size = size[loop];
            p_usw_scl_master[lchip]->ad_spool[index*SYS_SCL_SW_AD_TYPE_IGS_MAX + loop] = ctc_spool_create(&spool);
            if (NULL == p_usw_scl_master[lchip]->ad_spool[index*SYS_SCL_SW_AD_TYPE_IGS_MAX + loop])
            {
                ret = CTC_E_INIT_FAIL;
                goto error4;
            }
        }
    }


    /*acl profile spool*/
    spool.lchip = lchip;
    spool.block_num = 1;
    spool.block_size = 2 * MCHIP_CAP(SYS_CAP_SCL_ACL_CONTROL_PROFILE);
    spool.max_count = 2 * MCHIP_CAP(SYS_CAP_SCL_ACL_CONTROL_PROFILE);
    spool.user_data_size = sizeof(sys_scl_action_acl_t);
    spool.spool_key = (hash_key_fn) _sys_usw_scl_acl_profile_spool_make;
    spool.spool_cmp = (hash_cmp_fn) _sys_usw_scl_acl_profile_spool_compare;
    spool.spool_alloc = (spool_alloc_fn)_sys_usw_scl_acl_profile_spool_alloc_index;
    spool.spool_free = (spool_free_fn)_sys_usw_scl_acl_profile_spool_free_index;
    p_usw_scl_master[lchip]->acl_spool = ctc_spool_create(&spool);
    if (NULL == p_usw_scl_master[lchip]->acl_spool)
    {
        ret = CTC_E_INIT_FAIL;
        goto error5;
    }

    /*spool for compress ether type profile*/
    CTC_ERROR_GOTO(sys_usw_ftm_query_table_entry_num(lchip, UserIdEtherTypeCompressCam_t, &ceth_type_size), ret, error6);
    sal_memset(&spool, 0, sizeof(ctc_spool_t));
    spool.lchip = lchip;
    spool.block_num = 1;
    spool.block_size = ceth_type_size;
    spool.max_count = ceth_type_size;
    spool.user_data_size = sizeof(sys_register_cethertype_t);
    spool.desc = "opf-scl-cethertype";
    spool.key_size = CTC_OFFSET_OF(sys_register_cethertype_t, calc_len);
    spool.max_index = ceth_type_size - 1;
    p_usw_scl_master[lchip]->cethertype_spool = ctc_spool_create(&spool);
    if (!p_usw_scl_master[lchip]->cethertype_spool)
    {
        CTC_ERROR_GOTO(CTC_E_INIT_FAIL, ret, error6);
    }

    /* init count */
    sal_memset(p_usw_scl_master[lchip]->entry_count, 0, sizeof(p_usw_scl_master[lchip]->entry_count));

    CTC_ERROR_GOTO(_sys_usw_scl_init_opf(lchip), ret, free_cethertype_spool);
    CTC_ERROR_GOTO(_sys_usw_scl_init_fpa(lchip), ret, error7);
    CTC_ERROR_GOTO(_sys_usw_scl_init_build_key_and_action_cb(lchip), ret, error8);

    for (index=0; index<MCHIP_CAP(SYS_CAP_SCL_HASH_NUM); index+=1)
    {
        uint16 lport = 0;
        if(ad_num[index] == 0)
        {
            continue;
        }
        p_usw_scl_master[lchip]->igs_default_base[index] = ad_num[index] - 2*MCHIP_CAP(SYS_CAP_SCL_DEFAULT_ENTRY_BASE);
        for(lport = 0; lport < SYS_RSV_PORT_START; lport++)
        {
            if(sys_usw_chip_get_fwd_port_en(lchip, lport) == 0)
            {
                continue;
            }
            offset = p_usw_scl_master[lchip]->igs_default_base[index] + 2*lport;
            CTC_ERROR_GOTO(sys_usw_ftm_alloc_table_offset_from_position(lchip, ad_tbl[index], 0, 2, offset), ret, error8);
        }

        def_tunnel_num =  2*(DRV_ENUM(DRV_FROM_TMM(lchip) ? DRV_USERIDHASHTYPE_TUNNELIPV6CLOUDSEC : DRV_USERIDHASHTYPE_TUNNELIPV4DA)- DRV_ENUM(DRV_USERIDHASHTYPE_TUNNELIPV4) + 1);

        /** D2 and TM tunnle defualt entry base is same **/
        offset = DRV_FROM_TMM(lchip)  ? (p_usw_scl_master[lchip]->igs_default_base[index] - def_tunnel_num) : 0;
        p_usw_scl_master[lchip]->tunnel_default_base[index] = offset;
        CTC_ERROR_GOTO(sys_usw_ftm_alloc_table_offset_from_position(lchip, ad_tunnel[index], 0, def_tunnel_num, offset), ret, error8);
    }

    CTC_ERROR_GOTO(_sys_usw_scl_rsv_vlan_edit(lchip), ret, error8);

    CTC_ERROR_GOTO(_sys_usw_scl_init_default_entry(lchip), ret, error8);
    CTC_ERROR_GOTO(_sys_usw_scl_init_register(lchip, NULL), ret, error8); /* after init default entry */

    if(SYS_VCHIP_PP_IS_NOT_BASE(lchip))
    {
        p_usw_scl_master[lchip]->mutex = p_usw_scl_master[SYS_PP_BASE(lchip)]->mutex;
    }
    else
    {
        sal_mutex_create(&p_usw_scl_master[lchip]->mutex);
        if (NULL == p_usw_scl_master[lchip]->mutex)
        {
            ret = CTC_E_NO_MEMORY;
            goto error8;
        }
    }

    sys_usw_ftm_register_callback(lchip, CTC_FTM_SPEC_SCL, sys_usw_scl_ftm_scl_cb);
    sys_usw_ftm_register_callback(lchip, CTC_FTM_SPEC_SCL_TCAM, sys_usw_scl_ftm_ingress_tcam_cb);
    sys_usw_ftm_register_callback(lchip, CTC_FTM_SPEC_TUNNEL, sys_usw_scl_ftm_tunnel_cb);
    sys_usw_ftm_register_callback(lchip, CTC_FTM_SPEC_SCL_FLOW, sys_usw_scl_ftm_flow_cb);
    sys_usw_ftm_register_callback(lchip, CTC_FTM_SPEC_VLAN_XLATE, sys_usw_scl_ftm_xlate_cb);

    CTC_ERROR_GOTO(sys_usw_wb_sync_register_cb(lchip, CTC_FEATURE_SCL,SYS_WB_APPID_SCL_SUBID_MAX, sys_usw_scl_wb_sync), ret, error9);

    /* for DsSclFlow force decap use */
    cmd = DRV_IOW(IpeSclFlowCtl_t, IpeSclFlowCtl_removeByteShift_f);
    value = 1;
    DRV_FIELD_IOCTL(lchip, 0, DRV_CMD_BMP_EN(cmd, MCHIP_FEATURE_PP_EN(lchip,CTC_FEATURE_SCL)), &value);

    /* set chip_capability */
    spec_type = CTC_FTM_SPEC_SCL;
    sys_usw_ftm_get_profile_specs(lchip, spec_type, &spec_value);
    sys_usw_ftm_query_table_entry_num(lchip, DsUserIdPortHashKey_t, &entry_num);
    MCHIP_CAP(SYS_CAP_SPEC_SCL_HASH_ENTRY_NUM) = (entry_num < spec_value) ? entry_num : spec_value;
    if (1 == p_usw_scl_master[lchip]->hash_mode)
    {
        sys_usw_ftm_query_table_entry_num(lchip, DsUserId1PortHashKey_t, &entry_num);
        MCHIP_CAP(SYS_CAP_SPEC_SCL1_HASH_ENTRY_NUM) = (entry_num < spec_value) ? entry_num : spec_value;
    }
    else
    {
        sys_usw_ftm_query_table_entry_num(lchip, DsUserId1PortHashKey_t, &entry_num1);
        if ((entry_num != entry_num1) && !p_usw_scl_master[lchip]->hash_mode)
        {
            ret = CTC_E_NOT_INIT;
            goto error9;
        }
        MCHIP_CAP(SYS_CAP_SPEC_SCL1_HASH_ENTRY_NUM) = 0;
    }
    sys_usw_ftm_query_table_entry_num(lchip, DRV_FROM_TMM(lchip)? DsSclHash0ConflictTcamSize0_t: DsScl0MacKey160_t, &entry_num);
    MCHIP_CAP(SYS_CAP_SPEC_SCL0_IGS_TCAM_ENTRY_NUM) = entry_num;
    sys_usw_ftm_query_table_entry_num(lchip, DRV_FROM_TMM(lchip)? DsSclHash1ConflictTcamSize0_t: DsScl1MacKey160_t, &entry_num);
    MCHIP_CAP(SYS_CAP_SPEC_SCL1_IGS_TCAM_ENTRY_NUM) = entry_num;
    if (4 == MCHIP_CAP(SYS_CAP_SCL_IGS_TCAM_NUM))
    {
        sys_usw_ftm_query_table_entry_num(lchip, DsScl2MacKey160_t, &entry_num);
        MCHIP_CAP(SYS_CAP_SPEC_SCL2_IGS_TCAM_ENTRY_NUM) = entry_num;
        sys_usw_ftm_query_table_entry_num(lchip, DsScl3MacKey160_t, &entry_num);
        MCHIP_CAP(SYS_CAP_SPEC_SCL3_IGS_TCAM_ENTRY_NUM) = entry_num;
    }
    else
    {
        MCHIP_CAP(SYS_CAP_SPEC_SCL2_IGS_TCAM_ENTRY_NUM) = 0;
        MCHIP_CAP(SYS_CAP_SPEC_SCL3_IGS_TCAM_ENTRY_NUM) = 0;
    }
    MCHIP_CAP(SYS_CAP_SPEC_SCL_ENTRY_NUM) = MCHIP_CAP(SYS_CAP_SPEC_SCL_HASH_ENTRY_NUM) + MCHIP_CAP(SYS_CAP_SPEC_SCL1_HASH_ENTRY_NUM)
                        + MCHIP_CAP(SYS_CAP_SPEC_SCL0_IGS_TCAM_ENTRY_NUM) + MCHIP_CAP(SYS_CAP_SPEC_SCL1_IGS_TCAM_ENTRY_NUM)
                        + MCHIP_CAP(SYS_CAP_SPEC_SCL2_IGS_TCAM_ENTRY_NUM) + MCHIP_CAP(SYS_CAP_SPEC_SCL3_IGS_TCAM_ENTRY_NUM)
                        + p_usw_scl_master[lchip]->egs_entry_num[0] + p_usw_scl_master[lchip]->egs_entry_num[1]; /*SYS_WB_SCL_SUBID_HASH_KEY_ENTRY_NUM + SYS_WB_SCL_SUBID_TCAM_KEY_ENTRY_NUM*/;
    if (DRV_FROM_TMM(lchip))
    {
        uint32 egs_tcam0 = 0, egs_tcam1 = 0;
        sys_usw_ftm_query_table_entry_num(lchip, DsEgressScl0TcamKey_t, &egs_tcam0);
        sys_usw_ftm_query_table_entry_num(lchip, DsEgressScl1TcamKey_t, &egs_tcam1);
        MCHIP_CAP(SYS_CAP_SPEC_SCL_ENTRY_NUM) -= (egs_tcam0 + egs_tcam1);
    }

    if (CTC_WB_ENABLE(lchip) && CTC_WB_STATUS(lchip) == CTC_WB_STATUS_RELOADING)
    {
        CTC_ERROR_GOTO(sys_usw_scl_wb_restore(lchip), ret, error9);
    }

    if(CTC_WB_ENABLE(lchip))
    {
         _sys_usw_scl_init_wb(lchip);
    }
       /* for temp test*/
    if (!(CTC_WB_ENABLE(lchip) && CTC_WB_STATUS(lchip) == CTC_WB_STATUS_RELOADING) )
    {
        CTC_ERROR_GOTO(_sys_usw_scl_create_rsv_group(lchip), ret, error9);
    }
    CTC_ERROR_GOTO(sys_usw_dump_db_register_cb(lchip, CTC_FEATURE_SCL, sys_usw_scl_dump_db), ret, error9);

    sys_usw_mchip_set_feature_en(lchip,CTC_FEATURE_SCL);
    return CTC_E_NONE;

error9:
    sal_mutex_destroy(p_usw_scl_master[lchip]->mutex);
error8:
    for (index=0; index<MCHIP_CAP(SYS_CAP_SCL_HASH_NUM); index+=1)
    {
        offset = p_usw_scl_master[lchip]->igs_default_base[index];
        if (offset)
        {
            sys_usw_ftm_free_table_offset(lchip, ad_tbl[index], 0, 2*MCHIP_CAP(SYS_CAP_SCL_DEFAULT_ENTRY_BASE), offset);
        }

        offset = p_usw_scl_master[lchip]->tunnel_default_base[index];
        if (offset)
        {
            sys_usw_ftm_free_table_offset(lchip, ad_tunnel[index], 0, def_tunnel_num, offset);
        }
    }
    mem_free(p_usw_scl_master[lchip]->fpa);

    for(loop = 0; loop < MCHIP_CAP(SYS_CAP_SCL_TCAM_NUM); loop++)
    {
        mem_free(p_usw_scl_master[lchip]->fpa_block[loop].fpab.entries);
    }
error7:
    sys_usw_opf_deinit(lchip, p_usw_scl_master[lchip]->opf_type_vlan_edit);
    sys_usw_opf_deinit(lchip, p_usw_scl_master[lchip]->opf_type_entry_id);
    sys_usw_opf_deinit(lchip, p_usw_scl_master[lchip]->opf_type_flow_acl_profile);
    sys_usw_opf_deinit(lchip, p_usw_scl_master[lchip]->opf_type_tunnel_acl_profile);
free_cethertype_spool:
    ctc_spool_free(p_usw_scl_master[lchip]->cethertype_spool);
error6:
    ctc_spool_free(p_usw_scl_master[lchip]->acl_spool);
error5:
    for (loop = 0; loop < SYS_SCL_SW_AD_TYPE_IGS_MAX; loop++)
    {
        if (NULL != p_usw_scl_master[lchip]->ad_spool[SYS_SCL_SW_AD_TYPE_IGS_MAX+loop])
        {
            ctc_spool_free(p_usw_scl_master[lchip]->ad_spool[SYS_SCL_SW_AD_TYPE_IGS_MAX+loop]);
        }
    }

error4:
    for (loop = 0; loop < SYS_SCL_SW_AD_TYPE_IGS_MAX; loop++)
    {
        if (NULL != p_usw_scl_master[lchip]->ad_spool[loop])
        {
            ctc_spool_free(p_usw_scl_master[lchip]->ad_spool[loop]);
        }
    }
    ctc_spool_free(p_usw_scl_master[lchip]->vlan_edit_spool);
free_default_entry:
    ctc_vector_release(p_usw_scl_master[lchip]->default_entry);
free_flex_key:
    if (p_usw_scl_master[lchip]->flex_key_vec && !SYS_VCHIP_PP_IS_NOT_BASE(lchip))
    {
        ctc_vector_release(p_usw_scl_master[lchip]->flex_key_vec);
    }
free_kset:
    if (!SYS_VCHIP_PP_IS_NOT_BASE(lchip))
    {
        _sys_usw_scl_kset_deinit(lchip);
    }
error3:
    if (p_usw_scl_master[lchip]->tcam_entry_by_key)
    {
        ctc_hash_free(p_usw_scl_master[lchip]->tcam_entry_by_key);
    }
    ctc_hash_free(p_usw_scl_master[lchip]->hash_key_entry);
error2:
    ctc_hash_free(p_usw_scl_master[lchip]->entry);
error1:
    ctc_hash_free2(p_usw_scl_master[lchip]->group, (hash_traversal_fn) _sys_usw_scl_free_group_node_data, NULL);
error0:
    mem_free(p_usw_scl_master[lchip]);
    return ret;
}

int32
sys_usw_scl_deinit(uint8 lchip)
{
    uint8  idx  = 0;

    LCHIP_CHECK(lchip);
    if (NULL == p_usw_scl_master[lchip])
    {
        return CTC_E_NONE;
    }
    SYS_VCHIP_MASTER_DEINIT(lchip, p_usw_scl_master, CTC_FEATURE_SCL);
    sys_usw_ftm_register_callback(lchip, CTC_FTM_SPEC_SCL, NULL);
    sys_usw_ftm_register_callback(lchip, CTC_FTM_SPEC_SCL_TCAM, NULL);
    sys_usw_ftm_register_callback(lchip, CTC_FTM_SPEC_TUNNEL, NULL);
    sys_usw_ftm_register_callback(lchip, CTC_FTM_SPEC_SCL_FLOW, NULL);
    sys_usw_ftm_register_callback(lchip, CTC_FTM_SPEC_VLAN_XLATE, NULL);

    sys_usw_wb_sync_register_cb(lchip, CTC_FEATURE_SCL,0, NULL);
    sys_usw_dump_db_register_cb(lchip, CTC_FEATURE_SCL, NULL);
    /* free opf */
    sys_usw_opf_deinit(lchip, p_usw_scl_master[lchip]->opf_type_vlan_edit);
    sys_usw_opf_deinit(lchip, p_usw_scl_master[lchip]->opf_type_entry_id);
    sys_usw_opf_deinit(lchip, p_usw_scl_master[lchip]->opf_type_flow_acl_profile);
    sys_usw_opf_deinit(lchip, p_usw_scl_master[lchip]->opf_type_tunnel_acl_profile);

    /*free scl entry */
    ctc_hash_free2(p_usw_scl_master[lchip]->entry, (hash_traversal_fn)_sys_usw_scl_free_entry_node_data, &lchip);
    ctc_hash_free2(p_usw_scl_master[lchip]->hash_key_entry, (hash_traversal_fn)_sys_usw_scl_free_hash_key_node_data, NULL);
    ctc_hash_free2(p_usw_scl_master[lchip]->tcam_entry_by_key, (hash_traversal_fn)_sys_usw_scl_free_tcam_node_data, NULL);

     /*free ad */
     for (idx = 0; idx < MCHIP_CAP(SYS_CAP_SCL_HASH_NUM)*SYS_SCL_SW_AD_TYPE_IGS_MAX; idx += 1)
     {
        if(p_usw_scl_master[lchip]->ad_spool[idx])
        {
            ctc_spool_free(p_usw_scl_master[lchip]->ad_spool[idx]);
        }
     }

    /*free vlan edit spool */
    ctc_spool_free(p_usw_scl_master[lchip]->vlan_edit_spool);

    /*free acl profile spool */
    ctc_spool_free(p_usw_scl_master[lchip]->acl_spool);

    ctc_spool_free(p_usw_scl_master[lchip]->cethertype_spool);

    /*free scl group */
    ctc_hash_free2(p_usw_scl_master[lchip]->group, (hash_traversal_fn)_sys_usw_scl_free_group_node_data, NULL);

    if(MCHIP_SCL(lchip)->entry_pp_hash_deinit && MCHIP_FEATURE_PP_EN(lchip, CTC_FEATURE_SCL))
    {
        MCHIP_SCL(lchip)->entry_pp_hash_deinit(lchip);
    }

    /*free fpa entries*/
    for (idx = 0; idx < MCHIP_CAP(SYS_CAP_SCL_TCAM_NUM); idx++)
    {
        mem_free(p_usw_scl_master[lchip]->fpa_block[idx].fpab.entries);
    }

    /*free fpa */
    fpa_usw_free(p_usw_scl_master[lchip]->fpa);
    /*free flex key*/
    if (SYS_VCHIP_PP_IS_NOT_BASE(lchip))
    {
        p_usw_scl_master[lchip]->flex_key_vec = NULL;
    }
    else if (DRV_FROM_AT(lchip))
    {
        _sys_usw_scl_kset_deinit(lchip);
        ctc_vector_traverse(p_usw_scl_master[lchip]->flex_key_vec, (vector_traversal_fn)_sys_usw_scl_free_vec_node_data, NULL);
        ctc_vector_release(p_usw_scl_master[lchip]->flex_key_vec);
    }
    /*free default entry*/
    ctc_vector_traverse(p_usw_scl_master[lchip]->default_entry, _sys_usw_scl_free_entry_node_data, &lchip);
    ctc_vector_release(p_usw_scl_master[lchip]->default_entry);
    mem_free(p_usw_scl_master[lchip]->fpa_block);

    if(SYS_VCHIP_PP_IS_NOT_BASE(lchip))
    {
        p_usw_scl_master[lchip]->mutex = NULL;
    }
    else
    {
        sal_mutex_destroy(p_usw_scl_master[lchip]->mutex);
    }

    mem_free(p_usw_scl_master[lchip]);


    return CTC_E_NONE;
}

int32
sys_usw_scl_vlan_tag_op_translate(uint8 lchip, uint8 op_in, uint8* op_out, uint8* mode_out)
{
    if (CTC_VLAN_TAG_OP_REP_OR_ADD == op_in)
    {
        *mode_out = 1;
    }
    else
    {
        *mode_out = 0;
    }

    switch (op_in)
    {
        case CTC_VLAN_TAG_OP_NONE:
        case CTC_VLAN_TAG_OP_VALID:
            *op_out = DRV_ENUM(DRV_VTAGACTIONTYPE_NONE);
            break;
        case CTC_VLAN_TAG_OP_REP:
        case CTC_VLAN_TAG_OP_REP_OR_ADD:
            *op_out = DRV_ENUM(DRV_VTAGACTIONTYPE_MODIFY);
            break;
        case CTC_VLAN_TAG_OP_ADD:
            *op_out = DRV_ENUM(DRV_VTAGACTIONTYPE_ADD);
            break;
        case CTC_VLAN_TAG_OP_DEL:
            *op_out = DRV_ENUM(DRV_VTAGACTIONTYPE_DELETE);
            break;
    }
    return CTC_E_NONE;
}

int32
sys_usw_scl_vlan_tag_op_untranslate(uint8 lchip, uint8 op_in, uint8 mo_in, uint8* op_out)
{
    if(mo_in && (op_in==DRV_ENUM(DRV_VTAGACTIONTYPE_MODIFY)))
    {
        *op_out = CTC_VLAN_TAG_OP_REP_OR_ADD;
        return CTC_E_NONE;
    }

    if (op_in == DRV_ENUM(DRV_VTAGACTIONTYPE_NONE))
    {
        *op_out = CTC_VLAN_TAG_OP_NONE;
    }
    else if (op_in == DRV_ENUM(DRV_VTAGACTIONTYPE_MODIFY))
    {
        *op_out = CTC_VLAN_TAG_OP_REP;
    }
    else if (op_in == DRV_ENUM(DRV_VTAGACTIONTYPE_ADD))
    {
        *op_out = CTC_VLAN_TAG_OP_ADD;
    }
    else if (op_in == DRV_ENUM(DRV_VTAGACTIONTYPE_DELETE))
    {
        *op_out = CTC_VLAN_TAG_OP_DEL;
    }

    return CTC_E_NONE;
}

int32
sys_usw_scl_check_vlan_edit(uint8 lchip, ctc_scl_vlan_edit_t* p_sys, uint8* do_nothing)
{
    /* check tag op */
    CTC_MAX_VALUE_CHECK(p_sys->vlan_domain, CTC_SCL_VLAN_DOMAIN_MAX - 1);
    CTC_MAX_VALUE_CHECK(p_sys->stag_op, CTC_VLAN_TAG_OP_MAX - 1);
    CTC_MAX_VALUE_CHECK(p_sys->ctag_op, CTC_VLAN_TAG_OP_MAX - 1);

    if (0xFF != p_sys->tpid_index)
    {
        CTC_MAX_VALUE_CHECK(p_sys->tpid_index, 3);
    }

    if ((CTC_VLAN_TAG_OP_NONE == p_sys->stag_op) && (CTC_VLAN_TAG_OP_NONE == p_sys->ctag_op))
    {
        *do_nothing = 1;
        return CTC_E_NONE;
    }

    *do_nothing = 0;

    if ((CTC_VLAN_TAG_OP_ADD == p_sys->stag_op) \
        || (CTC_VLAN_TAG_OP_REP == p_sys->stag_op)
        || (CTC_VLAN_TAG_OP_REP_OR_ADD == p_sys->stag_op))
    {
        /* check stag select */
        if ((p_sys->svid_sl >= CTC_VLAN_TAG_SL_MAX)    \
            || (p_sys->scos_sl >= CTC_VLAN_TAG_SL_MAX) \
            || (p_sys->scfi_sl >= CTC_VLAN_TAG_SL_MAX))
        {
            return CTC_E_INVALID_PARAM;
        }
        if (CTC_VLAN_TAG_SL_NEW == p_sys->svid_sl)
        {
            if (p_sys->svid_new > CTC_MAX_VLAN_ID)
            {
                SYS_SCL_DBG_OUT(CTC_DEBUG_LEVEL_ERROR, " [Vlan] Invalid vlan id \n");
                return CTC_E_BADID;

            }
        }
        if (CTC_VLAN_TAG_SL_NEW == p_sys->scos_sl)
        {
            CTC_COS_RANGE_CHECK(p_sys->scos_new);
        }
        if (CTC_VLAN_TAG_SL_NEW == p_sys->scfi_sl)
        {
            CTC_MAX_VALUE_CHECK(p_sys->scfi_new, 1);
        }
    }

    if ((CTC_VLAN_TAG_OP_ADD == p_sys->ctag_op) \
        || (CTC_VLAN_TAG_OP_REP == p_sys->ctag_op)
        || (CTC_VLAN_TAG_OP_REP_OR_ADD == p_sys->ctag_op))
    {
        /* check ctag select */
        if ((p_sys->cvid_sl >= CTC_VLAN_TAG_SL_MAX)    \
            || (p_sys->ccos_sl >= CTC_VLAN_TAG_SL_MAX) \
            || (p_sys->ccfi_sl >= CTC_VLAN_TAG_SL_MAX))
        {
            return CTC_E_INVALID_PARAM;
        }
        if (CTC_VLAN_TAG_SL_NEW == p_sys->cvid_sl)
        {
            if (p_sys->cvid_new > CTC_MAX_VLAN_ID)
            {
                SYS_SCL_DBG_OUT(CTC_DEBUG_LEVEL_ERROR, " [Vlan] Invalid vlan id \n");
                return CTC_E_BADID;

            }
        }
        if (CTC_VLAN_TAG_SL_NEW == p_sys->ccos_sl)
        {
            CTC_COS_RANGE_CHECK(p_sys->ccos_new);
        }
        if (CTC_VLAN_TAG_SL_NEW == p_sys->ccfi_sl)
        {
            CTC_MAX_VALUE_CHECK(p_sys->ccfi_new, 1);
        }
    }

    return CTC_E_NONE;
}

int32
sys_usw_scl_get_acl_control_profile(uint8 lchip, uint8 is_tunnel, uint8* lkup_num, ctc_acl_property_t* p_acl_profile, void* p_buffer)
{
    uint8 offset          = 0;
    uint8 step            = 0;
    uint8 gport_type      = 0;
    uint8 sys_lkup_type   = 0;
    uint8 use_mapped_vlan = 0;
    uint8  loop           = 0;

    *lkup_num = 0;

    for(loop=0; loop < MCHIP_CAP(SYS_CAP_ACL_INGRESS_LKUP_NUM); loop++)
    {
        if (!is_tunnel)
        {
            step = DsSclAclControlProfile_gAcl_1_aclLookupType_f - DsSclAclControlProfile_gAcl_0_aclLookupType_f;
            offset = step * loop;
            sys_lkup_type = GetDsSclAclControlProfile(V, gAcl_0_aclLookupType_f + offset, p_buffer);
            gport_type = GetDsSclAclControlProfile(V, gAcl_0_aclUseGlobalPortType_f + offset, p_buffer);
            use_mapped_vlan = GetDsSclAclControlProfile(V, gAcl_0_aclUsePIVlan_f + offset, p_buffer);
        }
        if(sys_lkup_type)
        {
            p_acl_profile[*lkup_num].acl_en = 1;
            p_acl_profile[*lkup_num].acl_priority = loop;
            p_acl_profile[*lkup_num].tcam_lkup_type = sys_usw_unmap_acl_tcam_lkup_type(lchip, sys_lkup_type);
            if(use_mapped_vlan)
            {
                CTC_SET_FLAG(p_acl_profile[*lkup_num].flag, CTC_ACL_PROP_FLAG_USE_MAPPED_VLAN);
            }

            if(gport_type == DRV_ENUM(DRV_FLOWPORTTYPE_BITMAP))
            {
                CTC_SET_FLAG(p_acl_profile[*lkup_num].flag, CTC_ACL_PROP_FLAG_USE_PORT_BITMAP);
            }
            else if(gport_type == DRV_ENUM(DRV_FLOWPORTTYPE_LPORT))
            {
                CTC_SET_FLAG(p_acl_profile[*lkup_num].flag, CTC_ACL_PROP_FLAG_USE_LOGIC_PORT);
            }
            else if(gport_type == DRV_ENUM(DRV_FLOWPORTTYPE_METADATA))
            {
                CTC_SET_FLAG(p_acl_profile[*lkup_num].flag, CTC_ACL_PROP_FLAG_USE_METADATA);
            }
            (*lkup_num)++;
        }
    }

    return CTC_E_NONE;
}

void*
sys_usw_scl_add_vlan_edit_action_profile(uint8 lchip, ctc_scl_vlan_edit_t* vlan_edit, void* old_vlan_edit_profile)
{
    int32  ret = 0;
    sys_scl_sp_vlan_edit_t  new_vlan_edit;
    sys_scl_sp_vlan_edit_t* out_vlan_edit = NULL;

    sal_memset(&new_vlan_edit, 0, sizeof(sys_scl_sp_vlan_edit_t));

    _sys_usw_scl_mapping_vlan_edit(lchip, vlan_edit, &new_vlan_edit.action_profile);

    ret = ctc_spool_add(p_usw_scl_master[lchip]->vlan_edit_spool, &new_vlan_edit, old_vlan_edit_profile, &out_vlan_edit);
    if (ret != CTC_E_NONE)
    {
        ctc_spool_remove(p_usw_scl_master[lchip]->vlan_edit_spool, out_vlan_edit, NULL);
        return NULL;
    }

    SYS_SCL_DBG_OUT(CTC_DEBUG_LEVEL_INFO, "Add VlanActionProfileId: %d\n", out_vlan_edit->profile_id);

    return out_vlan_edit;
}

int32 sys_usw_scl_remove_vlan_edit_action_profile(uint8 lchip, sys_scl_sp_vlan_edit_t* p_vlan_edit)
{
    int32  ret = 0;

    SYS_SCL_INIT_CHECK();
    if (p_vlan_edit)
    {
        ret = ctc_spool_remove(p_usw_scl_master[lchip]->vlan_edit_spool, p_vlan_edit, NULL);
    }

    return ret ;
}

void*
sys_usw_scl_add_acl_control_profile(uint8 lchip,
                                     uint8 is_tunnel,
                                     uint8 lkup_num,
                                     ctc_acl_property_t acl_profile[CTC_MAX_ACL_LKUP_NUM],
                                     uint16* profile_id)
{
    int32  ret = CTC_E_NONE;
    uint8  loop = 0;

    sys_scl_action_acl_t  new_profile;
    sys_scl_action_acl_t* out_profile = NULL;

    sal_memset(&new_profile, 0, sizeof(sys_scl_action_acl_t));


    for (loop = 0 ; loop < lkup_num; loop++)
    {
        if(CTC_ACL_TCAM_LKUP_TYPE_VLAN == acl_profile[loop].tcam_lkup_type)
        {
            SYS_SCL_DBG_OUT(CTC_DEBUG_LEVEL_ERROR, "Acl not support tcam vlan key\n");
            return NULL;
        }
        _sys_usw_scl_mapping_acl_profile(lchip, is_tunnel, &acl_profile[loop], &new_profile.acl_control_profile);
    }

    new_profile.is_scl = !is_tunnel;

    ret = ctc_spool_add(p_usw_scl_master[lchip]->acl_spool, &new_profile, NULL, &out_profile);
    if (ret != CTC_E_NONE)
    {
        ctc_spool_remove(p_usw_scl_master[lchip]->acl_spool, out_profile, NULL);
        return NULL;
    }

    SYS_SCL_DBG_OUT(CTC_DEBUG_LEVEL_INFO, "Add acl control profile: %d\n", out_profile->profile_id);
    return out_profile ;
}

int32
sys_usw_scl_remove_acl_control_profile(uint8 lchip, sys_scl_action_acl_t* p_acl_profile)
{
    int32  ret = CTC_E_NONE;

    SYS_SCL_INIT_CHECK();
    if (p_acl_profile)
    {
        ret = ctc_spool_remove(p_usw_scl_master[lchip]->acl_spool, p_acl_profile, NULL);
        SYS_SCL_DBG_OUT(CTC_DEBUG_LEVEL_INFO, "Remove acl_control_profile: %d\n", p_acl_profile->profile_id);
    }

    return ret ;
}

